PostgreSQL Source Code  git master
geo_decls.h
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * geo_decls.h - Declarations for various 2D constructs.
4  *
5  *
6  * Portions Copyright (c) 1996-2021, 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 FPeq(double A, double B)
48 {
49  return A == B || fabs(A - B) <= EPSILON;
50 }
51 
52 static inline bool
53 FPne(double A, double B)
54 {
55  return A != B && fabs(A - B) > EPSILON;
56 }
57 
58 static inline bool
59 FPlt(double A, double B)
60 {
61  return A + EPSILON < B;
62 }
63 
64 static inline bool
65 FPle(double A, double B)
66 {
67  return A <= B + EPSILON;
68 }
69 
70 static inline bool
71 FPgt(double A, double B)
72 {
73  return A > B + EPSILON;
74 }
75 
76 static inline bool
77 FPge(double A, double B)
78 {
79  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!) */
119  int32 closed; /* is this a closed polygon? */
120  int32 dummy; /* padding to make it double align */
122 } PATH;
123 
124 
125 /*---------------------------------------------------------------------
126  * LINE - Specified by its general equation (Ax+By+C=0).
127  *-------------------------------------------------------------------*/
128 typedef struct
129 {
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!) */
157 } POLYGON;
158 
159 /*---------------------------------------------------------------------
160  * CIRCLE - Specified by a center point and radius.
161  *-------------------------------------------------------------------*/
162 typedef struct
163 {
166 } CIRCLE;
167 
168 /*
169  * fmgr interface macros
170  *
171  * Path and Polygon are toastable varlena types, the others are just
172  * fixed-size pass-by-reference types.
173  */
174 
175 #define DatumGetPointP(X) ((Point *) DatumGetPointer(X))
176 #define PointPGetDatum(X) PointerGetDatum(X)
177 #define PG_GETARG_POINT_P(n) DatumGetPointP(PG_GETARG_DATUM(n))
178 #define PG_RETURN_POINT_P(x) return PointPGetDatum(x)
179 
180 #define DatumGetLsegP(X) ((LSEG *) DatumGetPointer(X))
181 #define LsegPGetDatum(X) PointerGetDatum(X)
182 #define PG_GETARG_LSEG_P(n) DatumGetLsegP(PG_GETARG_DATUM(n))
183 #define PG_RETURN_LSEG_P(x) return LsegPGetDatum(x)
184 
185 #define DatumGetPathP(X) ((PATH *) PG_DETOAST_DATUM(X))
186 #define DatumGetPathPCopy(X) ((PATH *) PG_DETOAST_DATUM_COPY(X))
187 #define PathPGetDatum(X) PointerGetDatum(X)
188 #define PG_GETARG_PATH_P(n) DatumGetPathP(PG_GETARG_DATUM(n))
189 #define PG_GETARG_PATH_P_COPY(n) DatumGetPathPCopy(PG_GETARG_DATUM(n))
190 #define PG_RETURN_PATH_P(x) return PathPGetDatum(x)
191 
192 #define DatumGetLineP(X) ((LINE *) DatumGetPointer(X))
193 #define LinePGetDatum(X) PointerGetDatum(X)
194 #define PG_GETARG_LINE_P(n) DatumGetLineP(PG_GETARG_DATUM(n))
195 #define PG_RETURN_LINE_P(x) return LinePGetDatum(x)
196 
197 #define DatumGetBoxP(X) ((BOX *) DatumGetPointer(X))
198 #define BoxPGetDatum(X) PointerGetDatum(X)
199 #define PG_GETARG_BOX_P(n) DatumGetBoxP(PG_GETARG_DATUM(n))
200 #define PG_RETURN_BOX_P(x) return BoxPGetDatum(x)
201 
202 #define DatumGetPolygonP(X) ((POLYGON *) PG_DETOAST_DATUM(X))
203 #define DatumGetPolygonPCopy(X) ((POLYGON *) PG_DETOAST_DATUM_COPY(X))
204 #define PolygonPGetDatum(X) PointerGetDatum(X)
205 #define PG_GETARG_POLYGON_P(n) DatumGetPolygonP(PG_GETARG_DATUM(n))
206 #define PG_GETARG_POLYGON_P_COPY(n) DatumGetPolygonPCopy(PG_GETARG_DATUM(n))
207 #define PG_RETURN_POLYGON_P(x) return PolygonPGetDatum(x)
208 
209 #define DatumGetCircleP(X) ((CIRCLE *) DatumGetPointer(X))
210 #define CirclePGetDatum(X) PointerGetDatum(X)
211 #define PG_GETARG_CIRCLE_P(n) DatumGetCircleP(PG_GETARG_DATUM(n))
212 #define PG_RETURN_CIRCLE_P(x) return CirclePGetDatum(x)
213 
214 
215 /*
216  * in geo_ops.c
217  */
218 
219 extern float8 pg_hypot(float8 x, float8 y);
220 
221 #endif /* GEO_DECLS_H */
int32 dummy
Definition: geo_decls.h:120
static bool FPle(double A, double B)
Definition: geo_decls.h:65
Definition: geo_decls.h:140
float8 C
Definition: geo_decls.h:130
int32 closed
Definition: geo_decls.h:119
float8 radius
Definition: geo_decls.h:165
#define FLEXIBLE_ARRAY_MEMBER
Definition: c.h:350
float8 pg_hypot(float8 x, float8 y)
Definition: geo_ops.c:5526
int32 npts
Definition: geo_decls.h:154
signed int int32
Definition: c.h:429
double float8
Definition: c.h:565
int32 npts
Definition: geo_decls.h:118
static bool FPne(double A, double B)
Definition: geo_decls.h:53
Point low
Definition: geo_decls.h:142
int32 vl_len_
Definition: geo_decls.h:117
BOX boundbox
Definition: geo_decls.h:155
float8 y
Definition: geo_decls.h:98
static bool FPgt(double A, double B)
Definition: geo_decls.h:71
Point center
Definition: geo_decls.h:164
static bool FPeq(double A, double B)
Definition: geo_decls.h:47
#define EPSILON
Definition: geo_decls.h:41
int32 vl_len_
Definition: geo_decls.h:153
static bool FPge(double A, double B)
Definition: geo_decls.h:77
static bool FPlt(double A, double B)
Definition: geo_decls.h:59