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-2024, 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 
46 static inline bool
47 FPeq(double A, double B)
48 {
49  return A == B || fabs(A - B) <= EPSILON;
50 }
51 
52 static inline bool
53 FPne(double A, double B)
54 {
55  return A != B && fabs(A - B) > EPSILON;
56 }
57 
58 static inline bool
59 FPlt(double A, double B)
60 {
61  return A + EPSILON < B;
62 }
63 
64 static inline bool
65 FPle(double A, double B)
66 {
67  return A <= B + EPSILON;
68 }
69 
70 static inline bool
71 FPgt(double A, double B)
72 {
73  return A > B + EPSILON;
74 }
75 
76 static inline bool
77 FPge(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  *-------------------------------------------------------------------*/
96 typedef struct
97 {
99  y;
100 } Point;
101 
102 
103 /*---------------------------------------------------------------------
104  * LSEG - A straight line, specified by endpoints.
105  *-------------------------------------------------------------------*/
106 typedef struct
107 {
108  Point p[2];
109 } LSEG;
110 
111 
112 /*---------------------------------------------------------------------
113  * PATH - Specified by vertex points.
114  *-------------------------------------------------------------------*/
115 typedef 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  *-------------------------------------------------------------------*/
128 typedef struct
129 {
131  B,
132  C;
133 } LINE;
134 
135 
136 /*---------------------------------------------------------------------
137  * BOX - Specified by two corner points, which are
138  * sorted to save calculation time later.
139  *-------------------------------------------------------------------*/
140 typedef 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  *-------------------------------------------------------------------*/
151 typedef 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  *-------------------------------------------------------------------*/
162 typedef 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 
175 static inline Point *
177 {
178  return (Point *) DatumGetPointer(X);
179 }
180 static 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 
188 static inline LSEG *
190 {
191  return (LSEG *) DatumGetPointer(X);
192 }
193 static 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 
201 static inline PATH *
203 {
204  return (PATH *) PG_DETOAST_DATUM(X);
205 }
206 static inline PATH *
208 {
209  return (PATH *) PG_DETOAST_DATUM_COPY(X);
210 }
211 static 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 
220 static inline LINE *
222 {
223  return (LINE *) DatumGetPointer(X);
224 }
225 static 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 
233 static inline BOX *
235 {
236  return (BOX *) DatumGetPointer(X);
237 }
238 static inline Datum
239 BoxPGetDatum(const BOX *X)
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 
246 static inline POLYGON *
248 {
249  return (POLYGON *) PG_DETOAST_DATUM(X);
250 }
251 static inline POLYGON *
253 {
254  return (POLYGON *) PG_DETOAST_DATUM_COPY(X);
255 }
256 static 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 
265 static inline CIRCLE *
267 {
268  return (CIRCLE *) DatumGetPointer(X);
269 }
270 static 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 
283 extern float8 pg_hypot(float8 x, float8 y);
284 
285 #endif /* GEO_DECLS_H */
signed int int32
Definition: c.h:494
double float8
Definition: c.h:630
#define FLEXIBLE_ARRAY_MEMBER
Definition: c.h:398
#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 LINE * DatumGetLineP(Datum X)
Definition: geo_decls.h:221
static bool FPlt(double A, double B)
Definition: geo_decls.h:59
static PATH * DatumGetPathP(Datum X)
Definition: geo_decls.h:202
static Point * DatumGetPointP(Datum X)
Definition: geo_decls.h:176
static POLYGON * DatumGetPolygonPCopy(Datum X)
Definition: geo_decls.h:252
static CIRCLE * DatumGetCircleP(Datum X)
Definition: geo_decls.h:266
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 POLYGON * DatumGetPolygonP(Datum X)
Definition: geo_decls.h:247
static BOX * DatumGetBoxP(Datum X)
Definition: geo_decls.h:234
static Datum LinePGetDatum(const LINE *X)
Definition: geo_decls.h:226
float8 pg_hypot(float8 x, float8 y)
Definition: geo_ops.c:5519
static Datum PointPGetDatum(const Point *X)
Definition: geo_decls.h:181
static bool FPne(double A, double B)
Definition: geo_decls.h:53
static Datum CirclePGetDatum(const CIRCLE *X)
Definition: geo_decls.h:271
static PATH * DatumGetPathPCopy(Datum X)
Definition: geo_decls.h:207
static bool FPgt(double A, double B)
Definition: geo_decls.h:71
static LSEG * DatumGetLsegP(Datum X)
Definition: geo_decls.h:189
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:72
int x
Definition: isn.c:71
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
uintptr_t Datum
Definition: postgres.h:64
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:312
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