Age Owner TLA Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * geo_decls.h - Declarations for various 2D constructs.
4 : *
5 : *
6 : * Portions Copyright (c) 1996-2023, 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
869 tgl 47 CBC 9167586 : FPeq(double A, double B)
48 : {
49 9167586 : return A == B || fabs(A - B) <= EPSILON;
50 : }
51 :
52 : static inline bool
53 192 : FPne(double A, double B)
54 : {
55 192 : return A != B && fabs(A - B) > EPSILON;
56 : }
57 :
58 : static inline bool
59 1478489 : FPlt(double A, double B)
60 : {
61 1478489 : return A + EPSILON < B;
62 : }
63 :
64 : static inline bool
65 1591095 : FPle(double A, double B)
66 : {
67 1591095 : return A <= B + EPSILON;
68 : }
69 :
70 : static inline bool
71 18113049 : FPgt(double A, double B)
72 : {
73 18113049 : return A > B + EPSILON;
74 : }
75 :
76 : static inline bool
77 558258 : FPge(double A, double B)
78 : {
79 558258 : 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 : {
98 : float8 x,
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!) */
118 : int32 npts;
119 : int32 closed; /* is this a closed polygon? */
120 : int32 dummy; /* padding to make it double align */
121 : Point p[FLEXIBLE_ARRAY_MEMBER];
122 : } PATH;
123 :
124 :
125 : /*---------------------------------------------------------------------
126 : * LINE - Specified by its general equation (Ax+By+C=0).
127 : *-------------------------------------------------------------------*/
128 : typedef struct
129 : {
130 : float8 A,
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 : {
142 : Point high,
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!) */
154 : int32 npts;
155 : BOX boundbox;
156 : Point p[FLEXIBLE_ARRAY_MEMBER];
157 : } POLYGON;
158 :
159 : /*---------------------------------------------------------------------
160 : * CIRCLE - Specified by a center point and radius.
161 : *-------------------------------------------------------------------*/
162 : typedef struct
163 : {
164 : Point center;
165 : float8 radius;
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 *
194 peter 176 GNC 57298500 : DatumGetPointP(Datum X)
177 : {
178 57298500 : return (Point *) DatumGetPointer(X);
179 : }
180 : static inline Datum
181 46295060 : PointPGetDatum(const Point *X)
182 : {
183 46295060 : return PointerGetDatum(X);
184 : }
185 : #define PG_GETARG_POINT_P(n) DatumGetPointP(PG_GETARG_DATUM(n))
8335 tgl 186 ECB : #define PG_RETURN_POINT_P(x) return PointPGetDatum(x)
187 :
188 : static inline LSEG *
194 peter 189 GNC 41501 : DatumGetLsegP(Datum X)
190 : {
191 41501 : return (LSEG *) DatumGetPointer(X);
192 : }
193 : static inline Datum
194 30785 : LsegPGetDatum(const LSEG *X)
195 : {
196 30785 : return PointerGetDatum(X);
197 : }
198 : #define PG_GETARG_LSEG_P(n) DatumGetLsegP(PG_GETARG_DATUM(n))
8335 tgl 199 ECB : #define PG_RETURN_LSEG_P(x) return LsegPGetDatum(x)
200 :
201 : static inline PATH *
194 peter 202 GNC 1423517 : DatumGetPathP(Datum X)
203 : {
204 1423517 : return (PATH *) PG_DETOAST_DATUM(X);
205 : }
206 : static inline PATH *
207 933 : DatumGetPathPCopy(Datum X)
208 : {
209 933 : return (PATH *) PG_DETOAST_DATUM_COPY(X);
210 : }
211 : static inline Datum
212 16433 : PathPGetDatum(const PATH *X)
213 : {
214 16433 : return PointerGetDatum(X);
215 : }
216 : #define PG_GETARG_PATH_P(n) DatumGetPathP(PG_GETARG_DATUM(n))
8289 tgl 217 ECB : #define PG_GETARG_PATH_P_COPY(n) DatumGetPathPCopy(PG_GETARG_DATUM(n))
218 : #define PG_RETURN_PATH_P(x) return PathPGetDatum(x)
8335 219 :
220 : static inline LINE *
194 peter 221 GNC 9704 : DatumGetLineP(Datum X)
222 : {
223 9704 : return (LINE *) DatumGetPointer(X);
224 : }
225 : static inline Datum
226 309 : LinePGetDatum(const LINE *X)
227 : {
228 309 : return PointerGetDatum(X);
229 : }
8335 tgl 230 ECB : #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 *
194 peter 234 GNC 48543195 : DatumGetBoxP(Datum X)
235 : {
236 48543195 : return (BOX *) DatumGetPointer(X);
237 : }
238 : static inline Datum
239 1296917 : BoxPGetDatum(const BOX *X)
240 : {
241 1296917 : 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 *
247 437832 : DatumGetPolygonP(Datum X)
248 : {
249 437832 : return (POLYGON *) PG_DETOAST_DATUM(X);
250 : }
251 : static inline POLYGON *
252 : DatumGetPolygonPCopy(Datum X)
253 : {
254 : return (POLYGON *) PG_DETOAST_DATUM_COPY(X);
255 : }
256 : static inline Datum
257 39612 : PolygonPGetDatum(const POLYGON *X)
258 : {
259 39612 : 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))
8053 bruce 263 ECB : #define PG_RETURN_POLYGON_P(x) return PolygonPGetDatum(x)
264 :
265 : static inline CIRCLE *
194 peter 266 GNC 171565 : DatumGetCircleP(Datum X)
267 : {
268 171565 : return (CIRCLE *) DatumGetPointer(X);
269 : }
270 : static inline Datum
271 100393 : CirclePGetDatum(const CIRCLE *X)
272 : {
273 100393 : return PointerGetDatum(X);
274 : }
275 : #define PG_GETARG_CIRCLE_P(n) DatumGetCircleP(PG_GETARG_DATUM(n))
8335 tgl 276 ECB : #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 :
2118 285 : #endif /* GEO_DECLS_H */
|