]> granicus.if.org Git - postgresql/blob - src/test/regress/regress.c
Date/Time updates from Thomas...
[postgresql] / src / test / regress / regress.c
1 /*
2  * $Header: /cvsroot/pgsql/src/test/regress/regress.c,v 1.5 1997/03/14 23:34:16 scrappy Exp $
3  */
4
5 #include <float.h>              /* faked on sunos */
6 #include <stdio.h>
7 #include <string.h>   /* for memset() */
8
9 #include <postgres.h>
10
11 #include "utils/geo_decls.h"    /* includes <math.h> */
12 #include "executor/executor.h"  /* For GetAttributeByName */
13
14 #define P_MAXDIG 12
15 #define LDELIM          '('
16 #define RDELIM          ')'
17 #define DELIM           ','
18
19 typedef void *TUPLE;
20
21 extern double *regress_dist_ptpath (Point *pt, PATH *path);
22 extern double *regress_path_dist (PATH *p1, PATH *p2);
23 extern PATH *poly2path (POLYGON *poly);
24 extern Point *interpt_pp (PATH *p1, PATH *p2);
25 extern void regress_lseg_construct (LSEG *lseg, Point *pt1, Point *pt2);
26 extern char overpaid (TUPLE tuple);
27 extern int boxarea (BOX *box);
28 extern char *reverse_c16 (char *string);
29
30 /*
31 ** Distance from a point to a path 
32 */
33 double *
34 regress_dist_ptpath(pt, path)
35     Point *pt;
36     PATH *path;
37 {
38     double *result;
39     double *tmp;
40     int i;
41     LSEG lseg;
42
43     switch (path->npts) {
44     case 0:
45         result = PALLOCTYPE(double);
46         *result = Abs((double) DBL_MAX);        /* +infinity */
47         break;
48     case 1:
49         result = point_distance(pt, &path->p[0]);
50         break;
51     default:
52         /*
53          * the distance from a point to a path is the smallest distance
54          * from the point to any of its constituent segments.
55          */
56         Assert(path->npts > 1);
57         result = PALLOCTYPE(double);
58         for (i = 0; i < path->npts - 1; ++i) {
59             regress_lseg_construct(&lseg, &path->p[i], &path->p[i+1]);
60             tmp = dist_ps(pt, &lseg);
61             if (i == 0 || *tmp < *result)
62                 *result = *tmp;
63             PFREE(tmp);
64
65         }
66         break;
67     }
68     return(result);
69 }
70
71 /* this essentially does a cartesian product of the lsegs in the
72    two paths, and finds the min distance between any two lsegs */
73 double *
74 regress_path_dist(p1, p2)
75     PATH *p1;
76     PATH *p2;
77 {
78     double *min, *tmp;
79     int i,j;
80     LSEG seg1, seg2;
81
82     regress_lseg_construct(&seg1, &p1->p[0], &p1->p[1]);
83     regress_lseg_construct(&seg2, &p2->p[0], &p2->p[1]);
84     min = lseg_distance(&seg1, &seg2);
85
86     for (i = 0; i < p1->npts - 1; i++)
87       for (j = 0; j < p2->npts - 1; j++)
88        {
89            regress_lseg_construct(&seg1, &p1->p[i], &p1->p[i+1]);
90            regress_lseg_construct(&seg2, &p2->p[j], &p2->p[j+1]);
91
92            if (*min < *(tmp = lseg_distance(&seg1, &seg2)))
93              *min = *tmp;
94            PFREE(tmp);
95        }
96
97     return(min);
98 }
99
100 PATH *
101 poly2path(poly)
102     POLYGON *poly;
103 {
104     int i;
105     char *output = (char *)PALLOC(2*(P_MAXDIG + 1)*poly->npts + 64);
106     char *outptr = output;
107     double *xp, *yp;
108
109     sprintf(outptr, "(1, %*d", P_MAXDIG, poly->npts);
110     xp = (double *) poly->pts;
111     yp = (double *) (poly->pts + (poly->npts * sizeof(double *)));
112
113     for (i=1; i<poly->npts; i++,xp++,yp++)
114      {
115          sprintf(outptr, ",%*g,%*g", P_MAXDIG, *xp, P_MAXDIG, *yp);
116          outptr += 2*(P_MAXDIG + 1);
117      }
118
119     *outptr++ = RDELIM;
120     *outptr = '\0';
121     return(path_in(outptr));
122 }
123
124 /* return the point where two paths intersect.  Assumes that they do. */
125 Point *
126 interpt_pp(p1,p2)
127     PATH *p1;
128     PATH *p2;
129 {
130         
131     Point *retval;
132     int i,j;
133     LSEG seg1, seg2;
134     LINE *ln;
135     bool found;  /* We've found the intersection */
136
137     found = false;  /* Haven't found it yet */
138
139     for (i = 0; i < p1->npts - 1 && !found; i++)
140       for (j = 0; j < p2->npts - 1 && !found; j++)
141        {
142            regress_lseg_construct(&seg1, &p1->p[i], &p1->p[i+1]);
143            regress_lseg_construct(&seg2, &p2->p[j], &p2->p[j+1]);
144            if (lseg_intersect(&seg1, &seg2)) found = true;
145        }
146
147     ln = line_construct_pp(&seg2.p[0], &seg2.p[1]);
148     retval = interpt_sl(&seg1, ln);
149     
150     return(retval);
151 }
152
153
154 /* like lseg_construct, but assume space already allocated */
155 void
156 regress_lseg_construct(lseg, pt1, pt2)
157     LSEG *lseg;
158     Point *pt1;
159     Point *pt2;
160 {
161     lseg->p[0].x = pt1->x;
162     lseg->p[0].y = pt1->y;
163     lseg->p[1].x = pt2->x;
164     lseg->p[1].y = pt2->y;
165     lseg->m = point_sl(pt1, pt2);
166 }
167
168
169 char overpaid(tuple)
170     TUPLE tuple;
171 {
172     bool isnull;
173     long salary;
174
175     salary = (long)GetAttributeByName(tuple, "salary", &isnull);
176     return(salary > 699);
177 }
178
179 typedef struct {
180         Point   center;
181         double  radius;
182 } CIRCLE;
183
184 extern CIRCLE *circle_in (char *str);
185 extern char *circle_out (CIRCLE *circle);
186 extern int pt_in_circle (Point *point, CIRCLE *circle);
187
188 #define NARGS   3
189
190 CIRCLE *
191 circle_in(str)
192 char    *str;
193 {
194         char    *p, *coord[NARGS], buf2[1000];
195         int     i;
196         CIRCLE  *result;
197
198         if (str == NULL)
199                 return(NULL);
200         for (i = 0, p = str; *p && i < NARGS && *p != RDELIM; p++)
201                 if (*p == ',' || (*p == LDELIM && !i))
202                         coord[i++] = p + 1;
203         if (i < NARGS - 1)
204                 return(NULL);
205         result = (CIRCLE *) palloc(sizeof(CIRCLE));
206         result->center.x = atof(coord[0]);
207         result->center.y = atof(coord[1]);
208         result->radius = atof(coord[2]);
209
210         sprintf(buf2, "circle_in: read (%f, %f, %f)\n", result->center.x,
211         result->center.y,result->radius);
212         return(result);
213 }
214
215 char *
216 circle_out(circle)
217     CIRCLE      *circle;
218 {
219     char        *result;
220
221     if (circle == NULL)
222         return(NULL);
223
224     result = (char *) palloc(60);
225     (void) sprintf(result, "(%g,%g,%g)",
226                    circle->center.x, circle->center.y, circle->radius);
227     return(result);
228 }
229
230 int
231 pt_in_circle(point, circle)
232         Point   *point;
233         CIRCLE  *circle;
234 {
235         extern double   point_dt();
236
237         return( point_dt(point, &circle->center) < circle->radius );
238 }
239
240 #define ABS(X) ((X) > 0 ? (X) : -(X))
241
242 int
243 boxarea(box)
244
245 BOX *box;
246
247 {
248         int width, height;
249
250         width  = ABS(box->xh - box->xl);
251         height = ABS(box->yh - box->yl);
252         return (width * height);
253 }
254
255 char *
256 reverse_c16(string)
257     char *string;
258 {
259     register i;
260     int len;
261     char *new_string;
262
263     if (!(new_string = palloc(16))) {
264         fprintf(stderr, "reverse_c16: palloc failed\n");
265         return(NULL);
266     }
267     memset(new_string, 0, 16);
268     for (i = 0; i < 16 && string[i]; ++i)
269         ;
270     if (i == 16 || !string[i])
271         --i;
272     len = i;
273     for (; i >= 0; --i)
274         new_string[len-i] = string[i];
275     return(new_string);
276 }