Age Owner Branch data TLA Line data Source code
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 : :
46 : : static inline bool
1851 tgl@sss.pgh.pa.us 47 :CBC 9166588 : FPeq(double A, double B)
48 : : {
49 [ + + + + ]: 9166588 : 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 : 1476970 : FPlt(double A, double B)
60 : : {
61 : 1476970 : 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 : 18114174 : FPgt(double A, double B)
72 : : {
73 : 18114174 : 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 : :
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 *
1176 peter@eisentraut.org 175 : 57294965 : DatumGetPointP(Datum X)
176 : : {
177 : 57294965 : return (Point *) DatumGetPointer(X);
178 : : }
179 : : static inline Datum
180 : 46307768 : PointPGetDatum(const Point *X)
181 : : {
182 : 46307768 : 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 : 48530455 : DatumGetBoxP(Datum X)
234 : : {
235 : 48530455 : return (BOX *) DatumGetPointer(X);
236 : : }
237 : : static inline Datum
238 : 1297732 : BoxPGetDatum(const BOX *X)
239 : : {
240 : 1297732 : 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 : 100393 : CirclePGetDatum(const CIRCLE *X)
271 : : {
272 : 100393 : 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 */
|