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