Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * geo_decls.h - Declarations for various 2D constructs.
4 : *
5 : *
6 : * Portions Copyright (c) 1996-2026, 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 9169355 : FPeq(double A, double B)
48 : {
49 9169355 : 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 1481080 : FPlt(double A, double B)
60 : {
61 1481080 : return A + EPSILON < B;
62 : }
63 :
64 : static inline bool
65 1591089 : FPle(double A, double B)
66 : {
67 1591089 : return A <= B + EPSILON;
68 : }
69 :
70 : static inline bool
71 18120563 : FPgt(double A, double B)
72 : {
73 18120563 : return A > B + EPSILON;
74 : }
75 :
76 : static inline bool
77 558254 : FPge(double A, double B)
78 : {
79 558254 : 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 :
92 : /*---------------------------------------------------------------------
93 : * Point - (x,y)
94 : *-------------------------------------------------------------------*/
95 : typedef struct
96 : {
97 : float8 x,
98 : y;
99 : } Point;
100 :
101 :
102 : /*---------------------------------------------------------------------
103 : * LSEG - A straight line, specified by endpoints.
104 : *-------------------------------------------------------------------*/
105 : typedef struct
106 : {
107 : Point p[2];
108 : } LSEG;
109 :
110 :
111 : /*---------------------------------------------------------------------
112 : * PATH - Specified by vertex points.
113 : *-------------------------------------------------------------------*/
114 : typedef struct
115 : {
116 : int32 vl_len_; /* varlena header (do not touch directly!) */
117 : int32 npts;
118 : int32 closed; /* is this a closed polygon? */
119 : int32 dummy; /* padding to make it double align */
120 : Point p[FLEXIBLE_ARRAY_MEMBER];
121 : } PATH;
122 :
123 :
124 : /*---------------------------------------------------------------------
125 : * LINE - Specified by its general equation (Ax+By+C=0).
126 : *-------------------------------------------------------------------*/
127 : typedef struct
128 : {
129 : float8 A,
130 : B,
131 : C;
132 : } LINE;
133 :
134 :
135 : /*---------------------------------------------------------------------
136 : * BOX - Specified by two corner points, which are
137 : * sorted to save calculation time later.
138 : *-------------------------------------------------------------------*/
139 : typedef struct
140 : {
141 : Point high,
142 : low; /* corner POINTs */
143 : } BOX;
144 :
145 : /*---------------------------------------------------------------------
146 : * POLYGON - Specified by an array of doubles defining the points,
147 : * keeping the number of points and the bounding box for
148 : * speed purposes.
149 : *-------------------------------------------------------------------*/
150 : typedef struct
151 : {
152 : int32 vl_len_; /* varlena header (do not touch directly!) */
153 : int32 npts;
154 : BOX boundbox;
155 : Point p[FLEXIBLE_ARRAY_MEMBER];
156 : } POLYGON;
157 :
158 : /*---------------------------------------------------------------------
159 : * CIRCLE - Specified by a center point and radius.
160 : *-------------------------------------------------------------------*/
161 : typedef struct
162 : {
163 : Point center;
164 : float8 radius;
165 : } CIRCLE;
166 :
167 : /*
168 : * fmgr interface functions
169 : *
170 : * Path and Polygon are toastable varlena types, the others are just
171 : * fixed-size pass-by-reference types.
172 : */
173 :
174 : static inline Point *
175 57332533 : DatumGetPointP(Datum X)
176 : {
177 57332533 : return (Point *) DatumGetPointer(X);
178 : }
179 : static inline Datum
180 46338757 : PointPGetDatum(const Point *X)
181 : {
182 46338757 : return PointerGetDatum(X);
183 : }
184 : #define PG_GETARG_POINT_P(n) DatumGetPointP(PG_GETARG_DATUM(n))
185 : #define PG_RETURN_POINT_P(x) return PointPGetDatum(x)
186 :
187 : static inline LSEG *
188 41501 : DatumGetLsegP(Datum X)
189 : {
190 41501 : return (LSEG *) DatumGetPointer(X);
191 : }
192 : static inline Datum
193 30785 : LsegPGetDatum(const LSEG *X)
194 : {
195 30785 : return PointerGetDatum(X);
196 : }
197 : #define PG_GETARG_LSEG_P(n) DatumGetLsegP(PG_GETARG_DATUM(n))
198 : #define PG_RETURN_LSEG_P(x) return LsegPGetDatum(x)
199 :
200 : static inline PATH *
201 1423517 : DatumGetPathP(Datum X)
202 : {
203 1423517 : return (PATH *) PG_DETOAST_DATUM(X);
204 : }
205 : static inline PATH *
206 933 : DatumGetPathPCopy(Datum X)
207 : {
208 933 : return (PATH *) PG_DETOAST_DATUM_COPY(X);
209 : }
210 : static inline Datum
211 16433 : PathPGetDatum(const PATH *X)
212 : {
213 16433 : return PointerGetDatum(X);
214 : }
215 : #define PG_GETARG_PATH_P(n) DatumGetPathP(PG_GETARG_DATUM(n))
216 : #define PG_GETARG_PATH_P_COPY(n) DatumGetPathPCopy(PG_GETARG_DATUM(n))
217 : #define PG_RETURN_PATH_P(x) return PathPGetDatum(x)
218 :
219 : static inline LINE *
220 9704 : DatumGetLineP(Datum X)
221 : {
222 9704 : return (LINE *) DatumGetPointer(X);
223 : }
224 : static inline Datum
225 309 : LinePGetDatum(const LINE *X)
226 : {
227 309 : return PointerGetDatum(X);
228 : }
229 : #define PG_GETARG_LINE_P(n) DatumGetLineP(PG_GETARG_DATUM(n))
230 : #define PG_RETURN_LINE_P(x) return LinePGetDatum(x)
231 :
232 : static inline BOX *
233 48552545 : DatumGetBoxP(Datum X)
234 : {
235 48552545 : return (BOX *) DatumGetPointer(X);
236 : }
237 : static inline Datum
238 1297537 : BoxPGetDatum(const BOX *X)
239 : {
240 1297537 : return PointerGetDatum(X);
241 : }
242 : #define PG_GETARG_BOX_P(n) DatumGetBoxP(PG_GETARG_DATUM(n))
243 : #define PG_RETURN_BOX_P(x) return BoxPGetDatum(x)
244 :
245 : static inline POLYGON *
246 437832 : DatumGetPolygonP(Datum X)
247 : {
248 437832 : return (POLYGON *) PG_DETOAST_DATUM(X);
249 : }
250 : static inline POLYGON *
251 : DatumGetPolygonPCopy(Datum X)
252 : {
253 : return (POLYGON *) PG_DETOAST_DATUM_COPY(X);
254 : }
255 : static inline Datum
256 39612 : PolygonPGetDatum(const POLYGON *X)
257 : {
258 39612 : return PointerGetDatum(X);
259 : }
260 : #define PG_GETARG_POLYGON_P(n) DatumGetPolygonP(PG_GETARG_DATUM(n))
261 : #define PG_GETARG_POLYGON_P_COPY(n) DatumGetPolygonPCopy(PG_GETARG_DATUM(n))
262 : #define PG_RETURN_POLYGON_P(x) return PolygonPGetDatum(x)
263 :
264 : static inline CIRCLE *
265 171565 : DatumGetCircleP(Datum X)
266 : {
267 171565 : return (CIRCLE *) DatumGetPointer(X);
268 : }
269 : static inline Datum
270 100396 : CirclePGetDatum(const CIRCLE *X)
271 : {
272 100396 : return PointerGetDatum(X);
273 : }
274 : #define PG_GETARG_CIRCLE_P(n) DatumGetCircleP(PG_GETARG_DATUM(n))
275 : #define PG_RETURN_CIRCLE_P(x) return CirclePGetDatum(x)
276 :
277 : #endif /* GEO_DECLS_H */
|