1 | /*------------------------------------------------------------------------- |
2 | * |
3 | * geo_decls.h - Declarations for various 2D constructs. |
4 | * |
5 | * |
6 | * Portions Copyright (c) 1996-2019, 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 "fmgr.h" |
22 | |
23 | /*-------------------------------------------------------------------- |
24 | * Useful floating point utilities and constants. |
25 | *------------------------------------------------------------------- |
26 | * |
27 | * XXX: They are not NaN-aware. |
28 | */ |
29 | |
30 | #define EPSILON 1.0E-06 |
31 | |
32 | #ifdef EPSILON |
33 | #define FPzero(A) (fabs(A) <= EPSILON) |
34 | #define FPeq(A,B) (fabs((A) - (B)) <= EPSILON) |
35 | #define FPne(A,B) (fabs((A) - (B)) > EPSILON) |
36 | #define FPlt(A,B) ((B) - (A) > EPSILON) |
37 | #define FPle(A,B) ((A) - (B) <= EPSILON) |
38 | #define FPgt(A,B) ((A) - (B) > EPSILON) |
39 | #define FPge(A,B) ((B) - (A) <= EPSILON) |
40 | #else |
41 | #define FPzero(A) ((A) == 0) |
42 | #define FPeq(A,B) ((A) == (B)) |
43 | #define FPne(A,B) ((A) != (B)) |
44 | #define FPlt(A,B) ((A) < (B)) |
45 | #define FPle(A,B) ((A) <= (B)) |
46 | #define FPgt(A,B) ((A) > (B)) |
47 | #define FPge(A,B) ((A) >= (B)) |
48 | #endif |
49 | |
50 | #define HYPOT(A, B) pg_hypot(A, B) |
51 | |
52 | /*--------------------------------------------------------------------- |
53 | * Point - (x,y) |
54 | *-------------------------------------------------------------------*/ |
55 | typedef struct |
56 | { |
57 | float8 x, |
58 | y; |
59 | } Point; |
60 | |
61 | |
62 | /*--------------------------------------------------------------------- |
63 | * LSEG - A straight line, specified by endpoints. |
64 | *-------------------------------------------------------------------*/ |
65 | typedef struct |
66 | { |
67 | Point p[2]; |
68 | } LSEG; |
69 | |
70 | |
71 | /*--------------------------------------------------------------------- |
72 | * PATH - Specified by vertex points. |
73 | *-------------------------------------------------------------------*/ |
74 | typedef struct |
75 | { |
76 | int32 vl_len_; /* varlena header (do not touch directly!) */ |
77 | int32 npts; |
78 | int32 closed; /* is this a closed polygon? */ |
79 | int32 dummy; /* padding to make it double align */ |
80 | Point p[FLEXIBLE_ARRAY_MEMBER]; |
81 | } PATH; |
82 | |
83 | |
84 | /*--------------------------------------------------------------------- |
85 | * LINE - Specified by its general equation (Ax+By+C=0). |
86 | *-------------------------------------------------------------------*/ |
87 | typedef struct |
88 | { |
89 | float8 A, |
90 | B, |
91 | C; |
92 | } LINE; |
93 | |
94 | |
95 | /*--------------------------------------------------------------------- |
96 | * BOX - Specified by two corner points, which are |
97 | * sorted to save calculation time later. |
98 | *-------------------------------------------------------------------*/ |
99 | typedef struct |
100 | { |
101 | Point high, |
102 | low; /* corner POINTs */ |
103 | } BOX; |
104 | |
105 | /*--------------------------------------------------------------------- |
106 | * POLYGON - Specified by an array of doubles defining the points, |
107 | * keeping the number of points and the bounding box for |
108 | * speed purposes. |
109 | *-------------------------------------------------------------------*/ |
110 | typedef struct |
111 | { |
112 | int32 vl_len_; /* varlena header (do not touch directly!) */ |
113 | int32 npts; |
114 | BOX boundbox; |
115 | Point p[FLEXIBLE_ARRAY_MEMBER]; |
116 | } POLYGON; |
117 | |
118 | /*--------------------------------------------------------------------- |
119 | * CIRCLE - Specified by a center point and radius. |
120 | *-------------------------------------------------------------------*/ |
121 | typedef struct |
122 | { |
123 | Point center; |
124 | float8 radius; |
125 | } CIRCLE; |
126 | |
127 | /* |
128 | * fmgr interface macros |
129 | * |
130 | * Path and Polygon are toastable varlena types, the others are just |
131 | * fixed-size pass-by-reference types. |
132 | */ |
133 | |
134 | #define DatumGetPointP(X) ((Point *) DatumGetPointer(X)) |
135 | #define PointPGetDatum(X) PointerGetDatum(X) |
136 | #define PG_GETARG_POINT_P(n) DatumGetPointP(PG_GETARG_DATUM(n)) |
137 | #define PG_RETURN_POINT_P(x) return PointPGetDatum(x) |
138 | |
139 | #define DatumGetLsegP(X) ((LSEG *) DatumGetPointer(X)) |
140 | #define LsegPGetDatum(X) PointerGetDatum(X) |
141 | #define PG_GETARG_LSEG_P(n) DatumGetLsegP(PG_GETARG_DATUM(n)) |
142 | #define PG_RETURN_LSEG_P(x) return LsegPGetDatum(x) |
143 | |
144 | #define DatumGetPathP(X) ((PATH *) PG_DETOAST_DATUM(X)) |
145 | #define DatumGetPathPCopy(X) ((PATH *) PG_DETOAST_DATUM_COPY(X)) |
146 | #define PathPGetDatum(X) PointerGetDatum(X) |
147 | #define PG_GETARG_PATH_P(n) DatumGetPathP(PG_GETARG_DATUM(n)) |
148 | #define PG_GETARG_PATH_P_COPY(n) DatumGetPathPCopy(PG_GETARG_DATUM(n)) |
149 | #define PG_RETURN_PATH_P(x) return PathPGetDatum(x) |
150 | |
151 | #define DatumGetLineP(X) ((LINE *) DatumGetPointer(X)) |
152 | #define LinePGetDatum(X) PointerGetDatum(X) |
153 | #define PG_GETARG_LINE_P(n) DatumGetLineP(PG_GETARG_DATUM(n)) |
154 | #define PG_RETURN_LINE_P(x) return LinePGetDatum(x) |
155 | |
156 | #define DatumGetBoxP(X) ((BOX *) DatumGetPointer(X)) |
157 | #define BoxPGetDatum(X) PointerGetDatum(X) |
158 | #define PG_GETARG_BOX_P(n) DatumGetBoxP(PG_GETARG_DATUM(n)) |
159 | #define PG_RETURN_BOX_P(x) return BoxPGetDatum(x) |
160 | |
161 | #define DatumGetPolygonP(X) ((POLYGON *) PG_DETOAST_DATUM(X)) |
162 | #define DatumGetPolygonPCopy(X) ((POLYGON *) PG_DETOAST_DATUM_COPY(X)) |
163 | #define PolygonPGetDatum(X) PointerGetDatum(X) |
164 | #define PG_GETARG_POLYGON_P(n) DatumGetPolygonP(PG_GETARG_DATUM(n)) |
165 | #define PG_GETARG_POLYGON_P_COPY(n) DatumGetPolygonPCopy(PG_GETARG_DATUM(n)) |
166 | #define PG_RETURN_POLYGON_P(x) return PolygonPGetDatum(x) |
167 | |
168 | #define DatumGetCircleP(X) ((CIRCLE *) DatumGetPointer(X)) |
169 | #define CirclePGetDatum(X) PointerGetDatum(X) |
170 | #define PG_GETARG_CIRCLE_P(n) DatumGetCircleP(PG_GETARG_DATUM(n)) |
171 | #define PG_RETURN_CIRCLE_P(x) return CirclePGetDatum(x) |
172 | |
173 | |
174 | /* |
175 | * in geo_ops.c |
176 | */ |
177 | |
178 | extern float8 pg_hypot(float8 x, float8 y); |
179 | |
180 | #endif /* GEO_DECLS_H */ |
181 | |