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 12224646 : FPeq(double A, double B)
48 : {
49 12224646 : return A == B || fabs(A - B) <= EPSILON;
50 : }
51 :
52 : static inline bool
53 256 : FPne(double A, double B)
54 : {
55 256 : return A != B && fabs(A - B) > EPSILON;
56 : }
57 :
58 : static inline bool
59 1970496 : FPlt(double A, double B)
60 : {
61 1970496 : return A + EPSILON < B;
62 : }
63 :
64 : static inline bool
65 2121460 : FPle(double A, double B)
66 : {
67 2121460 : return A <= B + EPSILON;
68 : }
69 :
70 : static inline bool
71 24145325 : FPgt(double A, double B)
72 : {
73 24145325 : return A > B + EPSILON;
74 : }
75 :
76 : static inline bool
77 744344 : FPge(double A, double B)
78 : {
79 744344 : 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 76345672 : DatumGetPointP(Datum X)
176 : {
177 76345672 : return (Point *) DatumGetPointer(X);
178 : }
179 : static inline Datum
180 61735327 : PointPGetDatum(const Point *X)
181 : {
182 61735327 : 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 55321 : DatumGetLsegP(Datum X)
189 : {
190 55321 : return (LSEG *) DatumGetPointer(X);
191 : }
192 : static inline Datum
193 41046 : LsegPGetDatum(const LSEG *X)
194 : {
195 41046 : 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 1889857 : DatumGetPathP(Datum X)
202 : {
203 1889857 : return (PATH *) PG_DETOAST_DATUM(X);
204 : }
205 : static inline PATH *
206 1244 : DatumGetPathPCopy(Datum X)
207 : {
208 1244 : return (PATH *) PG_DETOAST_DATUM_COPY(X);
209 : }
210 : static inline Datum
211 21909 : PathPGetDatum(const PATH *X)
212 : {
213 21909 : 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 12928 : DatumGetLineP(Datum X)
221 : {
222 12928 : return (LINE *) DatumGetPointer(X);
223 : }
224 : static inline Datum
225 413 : LinePGetDatum(const LINE *X)
226 : {
227 413 : 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 64450538 : DatumGetBoxP(Datum X)
234 : {
235 64450538 : return (BOX *) DatumGetPointer(X);
236 : }
237 : static inline Datum
238 1716227 : BoxPGetDatum(const BOX *X)
239 : {
240 1716227 : 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 569086 : DatumGetPolygonP(Datum X)
247 : {
248 569086 : 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 52814 : PolygonPGetDatum(const POLYGON *X)
257 : {
258 52814 : 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 228739 : DatumGetCircleP(Datum X)
266 : {
267 228739 : return (CIRCLE *) DatumGetPointer(X);
268 : }
269 : static inline Datum
270 133864 : CirclePGetDatum(const CIRCLE *X)
271 : {
272 133864 : 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 */
|