/***********************************************************************
**
**	geo-decls.h
**
**	Declarations for various 2D constructs.
**
**	These routines do *not* use the float types from adt/.
**
**	XXX These routines were not written by a numerical analyst.
**
** Identification:
**	/usr/local/devel/postgres-4.2-devel/src/backend/utils/RCS/geo-decls.h,v 1.14 1994/02/07 11:46:33 aoki Exp
**
***********************************************************************/

#ifndef	GeoDeclsIncluded
#define	GeoDeclsIncluded

#ifndef FmgrIncluded
/*--------------------------------------------------------------------
 *	Useful floating point utilities and constants.
 *-------------------------------------------------------------------*/

#include <math.h>
#include "tmp/c.h"

#define	EPSILON			1.0E-06

#define	FPzero(A)		(fabs(A) <= EPSILON)
#define	FPeq(A,B)		(fabs((A) - (B)) <= EPSILON)
#define	FPlt(A,B)		((B) - (A) > EPSILON)
#define	FPle(A,B)		((A) - (B) <= EPSILON)
#define	FPgt(A,B)		((A) - (B) > EPSILON)
#define	FPge(A,B)		((B) - (A) <= EPSILON)

#define	HYPOT(A, B)		sqrt((A) * (A) + (B) * (B))

/*--------------------------------------------------------------------
 *	Memory management.
 *-------------------------------------------------------------------*/

#define	PALLOC(SIZE)		palloc(SIZE)
#define	PFREE(P)		pfree((char *) (P))
#define	PALLOCTYPE(TYPE)	(TYPE *) PALLOC(sizeof(TYPE))

/*--------------------------------------------------------------------
 *	Handy things...
 *-------------------------------------------------------------------*/

#ifdef sun
extern char *sprintf();
#endif sun

#endif !FmgrIncluded

/*---------------------------------------------------------------------
 *	POINT	-	(x,y)
 *-------------------------------------------------------------------*/
typedef struct {
	double	x, y;
} POINT;


/*---------------------------------------------------------------------
 *	LSEG	- 	A straight line, specified by endpoints.
 *-------------------------------------------------------------------*/
typedef	struct {
	POINT	p[2];

	double	m;	/* precomputed to save time, not in tuple */
} LSEG;


/*---------------------------------------------------------------------
 *	PATH	- 	Specified by vertex points.
 *-------------------------------------------------------------------*/
typedef	struct {
	int32	length;	/* XXX varlena */
	short	closed;	/* is this a closed polygon? */
	int32	npts;
	POINT	p[1];	/* variable length array of POINTs */
} PATH;


/*---------------------------------------------------------------------
 *	LINE	-	Specified by its general equation (Ax+By+C=0).
 *			If there is a y-intercept, it is C, which
 *			 incidentally gives a freebie point on the line
 *			 (if B=0, then C is the x-intercept).
 *			Slope m is precalculated to save time; if
 *			 the line is not vertical, m == A.
 *-------------------------------------------------------------------*/
typedef struct {
	double	A, B, C;
	double	m;
} LINE;


/*---------------------------------------------------------------------
 *	BOX	- 	Specified by two corner points, which are
 *			 sorted to save calculation time later.
 *-------------------------------------------------------------------*/
typedef struct {
	double	xh, yh, xl, yl;		/* high and low coords */
} BOX;

/*---------------------------------------------------------------------
 *  POLYGON - Specified by an array of doubles defining the points, 
 *			  keeping the number of points and the bounding box for 
 *			  speed purposes.
 *-------------------------------------------------------------------*/
typedef struct {
	int32 size;	/* XXX varlena */
	int32 npts;
	BOX boundbox;
	char pts[1];
} POLYGON;


/* ----------------------
 * function prototypes -- not called by function manager
 * automatically generated by mkproto
 * ----------------------
 */
extern BOX *box_in ARGS((char *str));
extern char *box_out ARGS((BOX *box));
extern BOX *box_construct ARGS((double x1, double x2, double y1, double y2));
extern BOX *box_fill ARGS((BOX *result, double x1, double x2, double y1, double y2));
extern BOX *box_copy ARGS((BOX *box));
extern long box_same ARGS((BOX *box1, BOX *box2));
extern long box_overlap ARGS((BOX *box1, BOX *box2));
extern long box_overleft ARGS((BOX *box1, BOX *box2));
extern long box_left ARGS((BOX *box1, BOX *box2));
extern long box_right ARGS((BOX *box1, BOX *box2));
extern long box_overright ARGS((BOX *box1, BOX *box2));
extern long box_contained ARGS((BOX *box1, BOX *box2));
extern long box_contain ARGS((BOX *box1, BOX *box2));
extern long box_below ARGS((BOX *box1, BOX *box2));
extern long box_above ARGS((BOX *box1, BOX *box2));
extern long box_lt ARGS((BOX *box1, BOX *box2));
extern long box_gt ARGS((BOX *box1, BOX *box2));
extern long box_eq ARGS((BOX *box1, BOX *box2));
extern long box_le ARGS((BOX *box1, BOX *box2));
extern long box_ge ARGS((BOX *box1, BOX *box2));
extern double *box_area ARGS((BOX *box));
extern double *box_length ARGS((BOX *box));
extern double *box_height ARGS((BOX *box));
extern double *box_distance ARGS((BOX *box1, BOX *box2));
extern POINT *box_center ARGS((BOX *box));
extern double box_ar ARGS((BOX *box));
extern double box_ln ARGS((BOX *box));
extern double box_ht ARGS((BOX *box));
extern double box_dt ARGS((BOX *box1, BOX *box2));
extern BOX *box_intersect ARGS((BOX *box1, BOX *box2));
extern LSEG *box_diagonal ARGS((BOX *box));
extern LINE *line_construct_pm ARGS((POINT *pt, double m));
extern LINE *line_construct_pp ARGS((POINT *pt1, POINT *pt2));
extern long line_intersect ARGS((LINE *l1, LINE *l2));
extern long line_parallel ARGS((LINE *l1, LINE *l2));
extern long line_perp ARGS((LINE *l1, LINE *l2));
extern long line_vertical ARGS((LINE *line));
extern long line_horizontal ARGS((LINE *line));
extern long line_eq ARGS((LINE *l1, LINE *l2));
extern double *line_distance ARGS((LINE *l1, LINE *l2));
extern POINT *line_interpt ARGS((LINE *l1, LINE *l2));
extern PATH *path_in ARGS((char *str));
extern char *path_out ARGS((PATH *path));
extern long path_n_lt ARGS((PATH *p1, PATH *p2));
extern long path_n_gt ARGS((PATH *p1, PATH *p2));
extern long path_n_eq ARGS((PATH *p1, PATH *p2));
extern long path_n_le ARGS((PATH *p1, PATH *p2));
extern long path_n_ge ARGS((PATH *p1, PATH *p2));
extern long path_inter ARGS((PATH *p1, PATH *p2));
extern double *path_distance ARGS((PATH *p1, PATH *p2));
extern double *path_length ARGS((PATH *path));
extern double path_ln ARGS((PATH *path));
extern POINT *point_in ARGS((char *str));
extern char *point_out ARGS((POINT *pt));
extern POINT *point_construct ARGS((double x, double y));
extern POINT *point_copy ARGS((POINT *pt));
extern long point_left ARGS((POINT *pt1, POINT *pt2));
extern long point_right ARGS((POINT *pt1, POINT *pt2));
extern long point_above ARGS((POINT *pt1, POINT *pt2));
extern long point_below ARGS((POINT *pt1, POINT *pt2));
extern long point_vert ARGS((POINT *pt1, POINT *pt2));
extern long point_horiz ARGS((POINT *pt1, POINT *pt2));
extern long point_eq ARGS((POINT *pt1, POINT *pt2));
extern long pointdist ARGS((POINT *p1, POINT *p2));
extern double *point_distance ARGS((POINT *pt1, POINT *pt2));
extern double point_dt ARGS((POINT *pt1, POINT *pt2));
extern double *point_slope ARGS((POINT *pt1, POINT *pt2));
extern double point_sl ARGS((POINT *pt1, POINT *pt2));
extern LSEG *lseg_in ARGS((char *str));
extern char *lseg_out ARGS((LSEG *ls));
extern LSEG *lseg_construct ARGS((POINT *pt1, POINT *pt2));
extern void statlseg_construct ARGS((LSEG *lseg, POINT *pt1, POINT *pt2));
extern long lseg_intersect ARGS((LSEG *l1, LSEG *l2));
extern long lseg_parallel ARGS((LSEG *l1, LSEG *l2));
extern long lseg_perp ARGS((LSEG *l1, LSEG *l2));
extern long lseg_vertical ARGS((LSEG *lseg));
extern long lseg_horizontal ARGS((LSEG *lseg));
extern long lseg_eq ARGS((LSEG *l1, LSEG *l2));
extern double *lseg_distance ARGS((LSEG *l1, LSEG *l2));
extern double lseg_dt ARGS((LSEG *l1, LSEG *l2));
extern POINT *lseg_interpt ARGS((LSEG *l1, LSEG *l2));
extern double *dist_pl ARGS((POINT *pt, LINE *line));
extern double *dist_ps ARGS((POINT *pt, LSEG *lseg));
extern double *dist_ppth ARGS((POINT *pt, PATH *path));
extern double *dist_pb ARGS((POINT *pt, BOX *box));
extern double *dist_sl ARGS((LSEG *lseg, LINE *line));
extern double *dist_sb ARGS((LSEG *lseg, BOX *box));
extern double *dist_lb ARGS((LINE *line, BOX *box));
extern POINT *interpt_sl ARGS((LSEG *lseg, LINE *line));
extern POINT *close_pl ARGS((POINT *pt, LINE *line));
extern POINT *close_ps ARGS((POINT *pt, LSEG *lseg));
extern POINT *close_pb ARGS((POINT *pt, BOX *box));
extern POINT *close_sl ARGS((LSEG *lseg, LINE *line));
extern POINT *close_sb ARGS((LSEG *lseg, BOX *box));
extern POINT *close_lb ARGS((LINE *line, BOX *box));
extern long on_pl ARGS((POINT *pt, LINE *line));
extern long on_ps ARGS((POINT *pt, LSEG *lseg));
extern long on_pb ARGS((POINT *pt, BOX *box));
extern long on_ppath ARGS((POINT *pt, PATH *path));
extern long on_sl ARGS((LSEG *lseg, LINE *line));
extern long on_sb ARGS((LSEG *lseg, BOX *box));
extern long inter_sl ARGS((LSEG *lseg, LINE *line));
extern long inter_sb ARGS((LSEG *lseg, BOX *box));
extern long inter_lb ARGS((LINE *line, BOX *box));
extern void make_bound_box ARGS((POLYGON *poly));
extern POLYGON *poly_in ARGS((char *s));
extern long poly_pt_count ARGS((char *s, int delim));
extern char *poly_out ARGS((POLYGON *poly));
extern double poly_max ARGS((double *coords, int ncoords));
extern double poly_min ARGS((double *coords, int ncoords));
extern long poly_left ARGS((POLYGON *polya, POLYGON *polyb));
extern long poly_overleft ARGS((POLYGON *polya, POLYGON *polyb));
extern long poly_right ARGS((POLYGON *polya, POLYGON *polyb));
extern long poly_overright ARGS((POLYGON *polya, POLYGON *polyb));
extern long poly_same ARGS((POLYGON *polya, POLYGON *polyb));
extern long poly_overlap ARGS((POLYGON *polya, POLYGON *polyb));
extern long poly_contain ARGS((POLYGON *polya, POLYGON *polyb));
extern long poly_contained ARGS((POLYGON *polya, POLYGON *polyb));

#endif /* !GeoDeclsIncluded */
