PostgreSQL Source Code git master
geo_decls.h
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * geo_decls.h - Declarations for various 2D constructs.
4 *
5 *
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 * src/include/utils/geo_decls.h
10 *
11 * XXX These routines were not written by a numerical analyst.
12 *
13 * XXX I have made some attempt to flesh out the operators
14 * and data types. There are still some more to do. - tgl 97/04/19
15 *
16 *-------------------------------------------------------------------------
17 */
18#ifndef GEO_DECLS_H
19#define GEO_DECLS_H
20
21#include <math.h>
22
23#include "fmgr.h"
24
25/*--------------------------------------------------------------------
26 * Useful floating point utilities and constants.
27 *--------------------------------------------------------------------
28 *
29 * "Fuzzy" floating-point comparisons: values within EPSILON of each other
30 * are considered equal. Beware of normal reasoning about the behavior of
31 * these comparisons, since for example FPeq does not behave transitively.
32 *
33 * Note that these functions are not NaN-aware and will give FALSE for
34 * any case involving NaN inputs.
35 *
36 * Also note that these will give sane answers for infinite inputs,
37 * where it's important to avoid computing Inf minus Inf; we do so
38 * by eliminating equality cases before subtracting.
39 */
40
41#define EPSILON 1.0E-06
42
43#ifdef EPSILON
44#define FPzero(A) (fabs(A) <= EPSILON)
45
46static inline bool
47FPeq(double A, double B)
48{
49 return A == B || fabs(A - B) <= EPSILON;
50}
51
52static inline bool
53FPne(double A, double B)
54{
55 return A != B && fabs(A - B) > EPSILON;
56}
57
58static inline bool
59FPlt(double A, double B)
60{
61 return A + EPSILON < B;
62}
63
64static inline bool
65FPle(double A, double B)
66{
67 return A <= B + EPSILON;
68}
69
70static inline bool
71FPgt(double A, double B)
72{
73 return A > B + EPSILON;
74}
75
76static inline bool
77FPge(double A, double B)
78{
79 return A + EPSILON >= B;
80}
81#else
82#define FPzero(A) ((A) == 0)
83#define FPeq(A,B) ((A) == (B))
84#define FPne(A,B) ((A) != (B))
85#define FPlt(A,B) ((A) < (B))
86#define FPle(A,B) ((A) <= (B))
87#define FPgt(A,B) ((A) > (B))
88#define FPge(A,B) ((A) >= (B))
89#endif
90
91#define HYPOT(A, B) pg_hypot(A, B)
92
93/*---------------------------------------------------------------------
94 * Point - (x,y)
95 *-------------------------------------------------------------------*/
96typedef struct
97{
100} Point;
101
102
103/*---------------------------------------------------------------------
104 * LSEG - A straight line, specified by endpoints.
105 *-------------------------------------------------------------------*/
106typedef struct
107{
108 Point p[2];
109} LSEG;
110
111
112/*---------------------------------------------------------------------
113 * PATH - Specified by vertex points.
114 *-------------------------------------------------------------------*/
115typedef struct
116{
117 int32 vl_len_; /* varlena header (do not touch directly!) */
119 int32 closed; /* is this a closed polygon? */
120 int32 dummy; /* padding to make it double align */
122} PATH;
123
124
125/*---------------------------------------------------------------------
126 * LINE - Specified by its general equation (Ax+By+C=0).
127 *-------------------------------------------------------------------*/
128typedef struct
129{
133} LINE;
134
135
136/*---------------------------------------------------------------------
137 * BOX - Specified by two corner points, which are
138 * sorted to save calculation time later.
139 *-------------------------------------------------------------------*/
140typedef struct
141{
143 low; /* corner POINTs */
144} BOX;
145
146/*---------------------------------------------------------------------
147 * POLYGON - Specified by an array of doubles defining the points,
148 * keeping the number of points and the bounding box for
149 * speed purposes.
150 *-------------------------------------------------------------------*/
151typedef struct
152{
153 int32 vl_len_; /* varlena header (do not touch directly!) */
157} POLYGON;
158
159/*---------------------------------------------------------------------
160 * CIRCLE - Specified by a center point and radius.
161 *-------------------------------------------------------------------*/
162typedef struct
163{
166} CIRCLE;
167
168/*
169 * fmgr interface functions
170 *
171 * Path and Polygon are toastable varlena types, the others are just
172 * fixed-size pass-by-reference types.
173 */
174
175static inline Point *
177{
178 return (Point *) DatumGetPointer(X);
179}
180static inline Datum
182{
183 return PointerGetDatum(X);
184}
185#define PG_GETARG_POINT_P(n) DatumGetPointP(PG_GETARG_DATUM(n))
186#define PG_RETURN_POINT_P(x) return PointPGetDatum(x)
187
188static inline LSEG *
190{
191 return (LSEG *) DatumGetPointer(X);
192}
193static inline Datum
195{
196 return PointerGetDatum(X);
197}
198#define PG_GETARG_LSEG_P(n) DatumGetLsegP(PG_GETARG_DATUM(n))
199#define PG_RETURN_LSEG_P(x) return LsegPGetDatum(x)
200
201static inline PATH *
203{
204 return (PATH *) PG_DETOAST_DATUM(X);
205}
206static inline PATH *
208{
209 return (PATH *) PG_DETOAST_DATUM_COPY(X);
210}
211static inline Datum
213{
214 return PointerGetDatum(X);
215}
216#define PG_GETARG_PATH_P(n) DatumGetPathP(PG_GETARG_DATUM(n))
217#define PG_GETARG_PATH_P_COPY(n) DatumGetPathPCopy(PG_GETARG_DATUM(n))
218#define PG_RETURN_PATH_P(x) return PathPGetDatum(x)
219
220static inline LINE *
222{
223 return (LINE *) DatumGetPointer(X);
224}
225static inline Datum
227{
228 return PointerGetDatum(X);
229}
230#define PG_GETARG_LINE_P(n) DatumGetLineP(PG_GETARG_DATUM(n))
231#define PG_RETURN_LINE_P(x) return LinePGetDatum(x)
232
233static inline BOX *
235{
236 return (BOX *) DatumGetPointer(X);
237}
238static inline Datum
240{
241 return PointerGetDatum(X);
242}
243#define PG_GETARG_BOX_P(n) DatumGetBoxP(PG_GETARG_DATUM(n))
244#define PG_RETURN_BOX_P(x) return BoxPGetDatum(x)
245
246static inline POLYGON *
248{
249 return (POLYGON *) PG_DETOAST_DATUM(X);
250}
251static inline POLYGON *
253{
254 return (POLYGON *) PG_DETOAST_DATUM_COPY(X);
255}
256static inline Datum
258{
259 return PointerGetDatum(X);
260}
261#define PG_GETARG_POLYGON_P(n) DatumGetPolygonP(PG_GETARG_DATUM(n))
262#define PG_GETARG_POLYGON_P_COPY(n) DatumGetPolygonPCopy(PG_GETARG_DATUM(n))
263#define PG_RETURN_POLYGON_P(x) return PolygonPGetDatum(x)
264
265static inline CIRCLE *
267{
268 return (CIRCLE *) DatumGetPointer(X);
269}
270static inline Datum
272{
273 return PointerGetDatum(X);
274}
275#define PG_GETARG_CIRCLE_P(n) DatumGetCircleP(PG_GETARG_DATUM(n))
276#define PG_RETURN_CIRCLE_P(x) return CirclePGetDatum(x)
277
278
279/*
280 * in geo_ops.c
281 */
282
283extern float8 pg_hypot(float8 x, float8 y);
284
285#endif /* GEO_DECLS_H */
double float8
Definition: c.h:587
#define FLEXIBLE_ARRAY_MEMBER
Definition: c.h:420
int32_t int32
Definition: c.h:484
#define PG_DETOAST_DATUM_COPY(datum)
Definition: fmgr.h:242
#define PG_DETOAST_DATUM(datum)
Definition: fmgr.h:240
#define EPSILON
Definition: geo_decls.h:41
static Datum PathPGetDatum(const PATH *X)
Definition: geo_decls.h:212
static bool FPlt(double A, double B)
Definition: geo_decls.h:59
static Datum LsegPGetDatum(const LSEG *X)
Definition: geo_decls.h:194
static bool FPge(double A, double B)
Definition: geo_decls.h:77
static Datum PolygonPGetDatum(const POLYGON *X)
Definition: geo_decls.h:257
static PATH * DatumGetPathPCopy(Datum X)
Definition: geo_decls.h:207
static POLYGON * DatumGetPolygonPCopy(Datum X)
Definition: geo_decls.h:252
static LINE * DatumGetLineP(Datum X)
Definition: geo_decls.h:221
static Point * DatumGetPointP(Datum X)
Definition: geo_decls.h:176
static Datum LinePGetDatum(const LINE *X)
Definition: geo_decls.h:226
static PATH * DatumGetPathP(Datum X)
Definition: geo_decls.h:202
float8 pg_hypot(float8 x, float8 y)
Definition: geo_ops.c:5519
static Datum PointPGetDatum(const Point *X)
Definition: geo_decls.h:181
static POLYGON * DatumGetPolygonP(Datum X)
Definition: geo_decls.h:247
static bool FPne(double A, double B)
Definition: geo_decls.h:53
static BOX * DatumGetBoxP(Datum X)
Definition: geo_decls.h:234
static CIRCLE * DatumGetCircleP(Datum X)
Definition: geo_decls.h:266
static Datum CirclePGetDatum(const CIRCLE *X)
Definition: geo_decls.h:271
static LSEG * DatumGetLsegP(Datum X)
Definition: geo_decls.h:189
static bool FPgt(double A, double B)
Definition: geo_decls.h:71
static bool FPle(double A, double B)
Definition: geo_decls.h:65
static Datum BoxPGetDatum(const BOX *X)
Definition: geo_decls.h:239
static bool FPeq(double A, double B)
Definition: geo_decls.h:47
int y
Definition: isn.c:71
int x
Definition: isn.c:70
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:327
uintptr_t Datum
Definition: postgres.h:69
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:317
Definition: geo_decls.h:141
Point low
Definition: geo_decls.h:143
Point high
Definition: geo_decls.h:142
float8 radius
Definition: geo_decls.h:165
Point center
Definition: geo_decls.h:164
float8 A
Definition: geo_decls.h:130
float8 B
Definition: geo_decls.h:131
float8 C
Definition: geo_decls.h:132
int32 vl_len_
Definition: geo_decls.h:117
int32 npts
Definition: geo_decls.h:118
int32 closed
Definition: geo_decls.h:119
int32 dummy
Definition: geo_decls.h:120
int32 vl_len_
Definition: geo_decls.h:153
int32 npts
Definition: geo_decls.h:154
BOX boundbox
Definition: geo_decls.h:155
float8 y
Definition: geo_decls.h:99
float8 x
Definition: geo_decls.h:98