aboutsummaryrefslogtreecommitdiff
path: root/src/test/regress/regress.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/regress/regress.c')
-rw-r--r--src/test/regress/regress.c271
1 files changed, 271 insertions, 0 deletions
diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c
new file mode 100644
index 00000000000..71d400f93dd
--- /dev/null
+++ b/src/test/regress/regress.c
@@ -0,0 +1,271 @@
+/*
+ * $Header: /cvsroot/pgsql/src/test/regress/regress.c,v 1.1.1.1 1996/07/09 06:22:24 scrappy Exp $
+ */
+
+#include <float.h> /* faked on sunos */
+#include <stdio.h>
+
+#include "utils/geo-decls.h" /* includes <math.h> */
+#include "libpq-fe.h"
+
+#define P_MAXDIG 12
+#define LDELIM '('
+#define RDELIM ')'
+#define DELIM ','
+
+extern double *regress_dist_ptpath (Point *pt, PATH *path);
+extern double *regress_path_dist (PATH *p1, PATH *p2);
+extern PATH *poly2path (POLYGON *poly);
+extern Point *interpt_pp (PATH *p1, PATH *p2);
+extern void regress_lseg_construct (LSEG *lseg, Point *pt1, Point *pt2);
+extern char overpaid (TUPLE tuple);
+extern int boxarea (BOX *box);
+extern char *reverse_c16 (char *string);
+
+/*
+** Distance from a point to a path
+*/
+double *
+regress_dist_ptpath(pt, path)
+ Point *pt;
+ PATH *path;
+{
+ double *result;
+ double *tmp;
+ int i;
+ LSEG lseg;
+
+ switch (path->npts) {
+ case 0:
+ result = PALLOCTYPE(double);
+ *result = Abs((double) DBL_MAX); /* +infinity */
+ break;
+ case 1:
+ result = point_distance(pt, &path->p[0]);
+ break;
+ default:
+ /*
+ * the distance from a point to a path is the smallest distance
+ * from the point to any of its constituent segments.
+ */
+ Assert(path->npts > 1);
+ result = PALLOCTYPE(double);
+ for (i = 0; i < path->npts - 1; ++i) {
+ regress_lseg_construct(&lseg, &path->p[i], &path->p[i+1]);
+ tmp = dist_ps(pt, &lseg);
+ if (i == 0 || *tmp < *result)
+ *result = *tmp;
+ PFREE(tmp);
+
+ }
+ break;
+ }
+ return(result);
+}
+
+/* this essentially does a cartesian product of the lsegs in the
+ two paths, and finds the min distance between any two lsegs */
+double *
+regress_path_dist(p1, p2)
+ PATH *p1;
+ PATH *p2;
+{
+ double *min, *tmp;
+ int i,j;
+ LSEG seg1, seg2;
+
+ regress_lseg_construct(&seg1, &p1->p[0], &p1->p[1]);
+ regress_lseg_construct(&seg2, &p2->p[0], &p2->p[1]);
+ min = lseg_distance(&seg1, &seg2);
+
+ for (i = 0; i < p1->npts - 1; i++)
+ for (j = 0; j < p2->npts - 1; j++)
+ {
+ regress_lseg_construct(&seg1, &p1->p[i], &p1->p[i+1]);
+ regress_lseg_construct(&seg2, &p2->p[j], &p2->p[j+1]);
+
+ if (*min < *(tmp = lseg_distance(&seg1, &seg2)))
+ *min = *tmp;
+ PFREE(tmp);
+ }
+
+ return(min);
+}
+
+PATH *
+poly2path(poly)
+ POLYGON *poly;
+{
+ int i;
+ char *output = (char *)PALLOC(2*(P_MAXDIG + 1)*poly->npts + 64);
+ char *outptr = output;
+ double *xp, *yp;
+
+ sprintf(outptr, "(1, %*d", P_MAXDIG, poly->npts);
+ xp = (double *) poly->pts;
+ yp = (double *) (poly->pts + (poly->npts * sizeof(double *)));
+
+ for (i=1; i<poly->npts; i++,xp++,yp++)
+ {
+ sprintf(outptr, ",%*g,%*g", P_MAXDIG, *xp, P_MAXDIG, *yp);
+ outptr += 2*(P_MAXDIG + 1);
+ }
+
+ *outptr++ = RDELIM;
+ *outptr = '\0';
+ return(path_in(outptr));
+}
+
+/* return the point where two paths intersect. Assumes that they do. */
+Point *
+interpt_pp(p1,p2)
+ PATH *p1;
+ PATH *p2;
+{
+
+ Point *retval;
+ int i,j;
+ LSEG seg1, seg2;
+ LINE *ln;
+
+ for (i = 0; i < p1->npts - 1; i++)
+ for (j = 0; j < p2->npts - 1; j++)
+ {
+ regress_lseg_construct(&seg1, &p1->p[i], &p1->p[i+1]);
+ regress_lseg_construct(&seg2, &p2->p[j], &p2->p[j+1]);
+ if (lseg_intersect(&seg1, &seg2))
+ {
+ ln = line_construct_pp(&seg2.p[0], &seg2.p[1]);
+ retval = interpt_sl(&seg1, ln);
+ goto exit;
+ }
+ }
+
+ exit:
+ return(retval);
+}
+
+
+/* like lseg_construct, but assume space already allocated */
+void
+regress_lseg_construct(lseg, pt1, pt2)
+ LSEG *lseg;
+ Point *pt1;
+ Point *pt2;
+{
+ lseg->p[0].x = pt1->x;
+ lseg->p[0].y = pt1->y;
+ lseg->p[1].x = pt2->x;
+ lseg->p[1].y = pt2->y;
+ lseg->m = point_sl(pt1, pt2);
+}
+
+
+char overpaid(tuple)
+ TUPLE tuple;
+{
+ bool isnull;
+ long salary;
+
+ salary = (long)GetAttributeByName(tuple, "salary", &isnull);
+ return(salary > 699);
+}
+
+typedef struct {
+ Point center;
+ double radius;
+} CIRCLE;
+
+extern CIRCLE *circle_in (char *str);
+extern char *circle_out (CIRCLE *circle);
+extern int pt_in_circle (Point *point, CIRCLE *circle);
+
+#define NARGS 3
+
+CIRCLE *
+circle_in(str)
+char *str;
+{
+ char *p, *coord[NARGS], buf2[1000];
+ int i;
+ CIRCLE *result;
+
+ if (str == NULL)
+ return(NULL);
+ for (i = 0, p = str; *p && i < NARGS && *p != RDELIM; p++)
+ if (*p == ',' || (*p == LDELIM && !i))
+ coord[i++] = p + 1;
+ if (i < NARGS - 1)
+ return(NULL);
+ result = (CIRCLE *) palloc(sizeof(CIRCLE));
+ result->center.x = atof(coord[0]);
+ result->center.y = atof(coord[1]);
+ result->radius = atof(coord[2]);
+
+ sprintf(buf2, "circle_in: read (%f, %f, %f)\n", result->center.x,
+ result->center.y,result->radius);
+ return(result);
+}
+
+char *
+circle_out(circle)
+ CIRCLE *circle;
+{
+ char *result;
+
+ if (circle == NULL)
+ return(NULL);
+
+ result = (char *) palloc(60);
+ (void) sprintf(result, "(%g,%g,%g)",
+ circle->center.x, circle->center.y, circle->radius);
+ return(result);
+}
+
+int
+pt_in_circle(point, circle)
+ Point *point;
+ CIRCLE *circle;
+{
+ extern double point_dt();
+
+ return( point_dt(point, &circle->center) < circle->radius );
+}
+
+#define ABS(X) ((X) > 0 ? (X) : -(X))
+
+int
+boxarea(box)
+
+BOX *box;
+
+{
+ int width, height;
+
+ width = ABS(box->xh - box->xl);
+ height = ABS(box->yh - box->yl);
+ return (width * height);
+}
+
+char *
+reverse_c16(string)
+ char *string;
+{
+ register i;
+ int len;
+ char *new_string;
+
+ if (!(new_string = palloc(16))) {
+ fprintf(stderr, "reverse_c16: palloc failed\n");
+ return(NULL);
+ }
+ memset(new_string, 0, 16);
+ for (i = 0; i < 16 && string[i]; ++i)
+ ;
+ if (i == 16 || !string[i])
+ --i;
+ len = i;
+ for (; i >= 0; --i)
+ new_string[len-i] = string[i];
+ return(new_string);
+}