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-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
1240 tgl@sss.pgh.pa.us 47 :CBC 9166632 : FPeq(double A, double B)
48 : : {
49 [ + + + + ]: 9166632 : 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 : 1476890 : FPlt(double A, double B)
60 : : {
61 : 1476890 : 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 : 18106197 : FPgt(double A, double B)
72 : : {
73 : 18106197 : 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 *
565 peter@eisentraut.org 176 : 57276652 : DatumGetPointP(Datum X)
177 : : {
178 : 57276652 : return (Point *) DatumGetPointer(X);
179 : : }
180 : : static inline Datum
181 : 46274499 : PointPGetDatum(const Point *X)
182 : : {
183 : 46274499 : 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 *
189 : 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))
199 : : #define PG_RETURN_LSEG_P(x) return LsegPGetDatum(x)
200 : :
201 : : static inline PATH *
202 : 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))
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 *
221 : 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 : : }
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 *
234 : 48590391 : DatumGetBoxP(Datum X)
235 : : {
236 : 48590391 : return (BOX *) DatumGetPointer(X);
237 : : }
238 : : static inline Datum
239 : 1297565 : BoxPGetDatum(const BOX *X)
240 : : {
241 : 1297565 : 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))
263 : : #define PG_RETURN_POLYGON_P(x) return PolygonPGetDatum(x)
264 : :
265 : : static inline CIRCLE *
266 : 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))
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 */
|