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