codekingpro/portable-devtools
114k
1/*-------------------------------------------------------------------------2 *3 * geo_decls.h - Declarations for various 2D constructs.4 *5 *6 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group7 * Portions Copyright (c) 1994, Regents of the University of California8 *9 * src/include/utils/geo_decls.h10 *11 * XXX These routines were not written by a numerical analyst.12 *13 * XXX I have made some attempt to flesh out the operators14 * and data types. There are still some more to do. - tgl 97/04/1915 *16 *-------------------------------------------------------------------------17 */18#ifndef GEO_DECLS_H19#define GEO_DECLS_H20 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 other30 * are considered equal. Beware of normal reasoning about the behavior of31 * these comparisons, since for example FPeq does not behave transitively.32 *33 * Note that these functions are not NaN-aware and will give FALSE for34 * 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 so38 * by eliminating equality cases before subtracting.39 */40 41#define EPSILON 1.0E-0642 43#ifdef EPSILON44#define FPzero(A) (fabs(A) <= EPSILON)45 46static inline bool47FPeq(double A, double B)48{49 return A == B || fabs(A - B) <= EPSILON;50}51 52static inline bool53FPne(double A, double B)54{55 return A != B && fabs(A - B) > EPSILON;56}57 58static inline bool59FPlt(double A, double B)60{61 return A + EPSILON < B;62}63 64static inline bool65FPle(double A, double B)66{67 return A <= B + EPSILON;68}69 70static inline bool71FPgt(double A, double B)72{73 return A > B + EPSILON;74}75 76static inline bool77FPge(double A, double B)78{79 return A + EPSILON >= B;80}81#else82#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#endif90 91#define HYPOT(A, B) pg_hypot(A, B)92 93/*---------------------------------------------------------------------94 * Point - (x,y)95 *-------------------------------------------------------------------*/96typedef struct97{98 float8 x,99 y;100} Point;101 102 103/*---------------------------------------------------------------------104 * LSEG - A straight line, specified by endpoints.105 *-------------------------------------------------------------------*/106typedef struct107{108 Point p[2];109} LSEG;110 111 112/*---------------------------------------------------------------------113 * PATH - Specified by vertex points.114 *-------------------------------------------------------------------*/115typedef struct116{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 *-------------------------------------------------------------------*/128typedef struct129{130 float8 A,131 B,132 C;133} LINE;134 135 136/*---------------------------------------------------------------------137 * BOX - Specified by two corner points, which are138 * sorted to save calculation time later.139 *-------------------------------------------------------------------*/140typedef struct141{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 for149 * speed purposes.150 *-------------------------------------------------------------------*/151typedef struct152{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 *-------------------------------------------------------------------*/162typedef struct163{164 Point center;165 float8 radius;166} CIRCLE;167 168/*169 * fmgr interface functions170 *171 * Path and Polygon are toastable varlena types, the others are just172 * fixed-size pass-by-reference types.173 */174 175static inline Point *176DatumGetPointP(Datum X)177{178 return (Point *) DatumGetPointer(X);179}180static inline Datum181PointPGetDatum(const Point *X)182{183 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 188static inline LSEG *189DatumGetLsegP(Datum X)190{191 return (LSEG *) DatumGetPointer(X);192}193static inline Datum194LsegPGetDatum(const LSEG *X)195{196 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 201static inline PATH *202DatumGetPathP(Datum X)203{204 return (PATH *) PG_DETOAST_DATUM(X);205}206static inline PATH *207DatumGetPathPCopy(Datum X)208{209 return (PATH *) PG_DETOAST_DATUM_COPY(X);210}211static inline Datum212PathPGetDatum(const PATH *X)213{214 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 220static inline LINE *221DatumGetLineP(Datum X)222{223 return (LINE *) DatumGetPointer(X);224}225static inline Datum226LinePGetDatum(const LINE *X)227{228 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 233static inline BOX *234DatumGetBoxP(Datum X)235{236 return (BOX *) DatumGetPointer(X);237}238static inline Datum239BoxPGetDatum(const BOX *X)240{241 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 246static inline POLYGON *247DatumGetPolygonP(Datum X)248{249 return (POLYGON *) PG_DETOAST_DATUM(X);250}251static inline POLYGON *252DatumGetPolygonPCopy(Datum X)253{254 return (POLYGON *) PG_DETOAST_DATUM_COPY(X);255}256static inline Datum257PolygonPGetDatum(const POLYGON *X)258{259 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 265static inline CIRCLE *266DatumGetCircleP(Datum X)267{268 return (CIRCLE *) DatumGetPointer(X);269}270static inline Datum271CirclePGetDatum(const CIRCLE *X)272{273 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.c281 */282 283extern float8 pg_hypot(float8 x, float8 y);284 285#endif /* GEO_DECLS_H */286 