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