regress.c 5.9 KB
Newer Older
1
/*
2
 * $Header: /cvsroot/pgsql/src/test/regress/regress.c,v 1.9 1997/08/19 21:40:56 momjian Exp $
3 4 5 6
 */

#include <float.h>		/* faked on sunos */
#include <stdio.h>
B
Bryan Henderson 已提交
7
#include <string.h>   /* for memset() */
8

M
Marc G. Fournier 已提交
9 10
#include <postgres.h>

11
#include "utils/geo_decls.h"	/* includes <math.h> */
B
Bryan Henderson 已提交
12
#include "executor/executor.h"  /* For GetAttributeByName */
13 14 15 16 17 18

#define P_MAXDIG 12
#define LDELIM		'('
#define RDELIM		')'
#define	DELIM		','

19 20
typedef void *TUPLE;

21 22 23 24 25 26 27 28 29 30 31 32
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 
*/
33
 double *
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
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 */
73
 double *
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
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);
}

100
 PATH *
101 102 103 104 105
poly2path(poly)
    POLYGON *poly;
{
    int i;
    char *output = (char *)PALLOC(2*(P_MAXDIG + 1)*poly->npts + 64);
106
    char buf[2*(P_MAXDIG)+20];
107

108
    sprintf(output, "(1, %*d", P_MAXDIG, poly->npts);
109

110
    for (i=0; i<poly->npts; i++)
111
     {
112 113
	 sprintf(buf, ",%*g,%*g", P_MAXDIG, poly->p[i].x, P_MAXDIG, poly->p[i].y);
	 strcat(output, buf);
114 115
     }

116 117 118
    sprintf(buf, "%c", RDELIM);
    strcat(output, buf);
    return(path_in(output));
119 120 121
}

/* return the point where two paths intersect.  Assumes that they do. */
122
 Point *
123 124 125 126 127 128 129 130
interpt_pp(p1,p2)
    PATH *p1;
    PATH *p2;
{
        
    Point *retval;
    int i,j;
    LSEG seg1, seg2;
131
#if FALSE
132
    LINE *ln;
133
#endif
B
Bryan Henderson 已提交
134
    bool found;  /* We've found the intersection */
135

B
Bryan Henderson 已提交
136 137 138 139
    found = false;  /* Haven't found it yet */

    for (i = 0; i < p1->npts - 1 && !found; i++)
      for (j = 0; j < p2->npts - 1 && !found; j++)
140
       {
B
Bryan Henderson 已提交
141 142 143
           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)) found = true;
144 145
       }

146
#if FALSE
B
Bryan Henderson 已提交
147 148
    ln = line_construct_pp(&seg2.p[0], &seg2.p[1]);
    retval = interpt_sl(&seg1, ln);
149 150
#endif
    retval = lseg_interpt( &seg1, &seg2);
B
Bryan Henderson 已提交
151
    
152 153 154 155 156
    return(retval);
}


/* like lseg_construct, but assume space already allocated */
157
 void
158 159 160 161 162 163 164 165 166 167 168 169 170
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);
}


171
 char overpaid(tuple)
172 173 174 175 176 177 178 179 180
    TUPLE tuple;
{
    bool isnull;
    long salary;

    salary = (long)GetAttributeByName(tuple, "salary", &isnull);
    return(salary > 699);
}

181 182 183 184 185
/* New type "widget"
 * This used to be "circle", but I added circle to builtins,
 *  so needed to make sure the names do not collide. - tgl 97/04/21
 */

186 187 188
typedef struct {
	Point	center;
	double	radius;
189
} WIDGET;
190

191 192 193
 WIDGET *widget_in (char *str);
 char *widget_out (WIDGET *widget);
 int pt_in_widget (Point *point, WIDGET *widget);
194 195 196

#define NARGS	3

197
 WIDGET *
198
widget_in(str)
199 200 201 202
char	*str;
{
	char	*p, *coord[NARGS], buf2[1000];
	int	i;
203
	WIDGET	*result;
204 205 206 207 208 209 210 211

	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);
212
	result = (WIDGET *) palloc(sizeof(WIDGET));
213 214 215 216
	result->center.x = atof(coord[0]);
	result->center.y = atof(coord[1]);
	result->radius = atof(coord[2]);

217
	sprintf(buf2, "widget_in: read (%f, %f, %f)\n", result->center.x,
218 219 220 221
	result->center.y,result->radius);
	return(result);
}

222
 char *
223 224
widget_out(widget)
    WIDGET	*widget;
225 226 227
{
    char	*result;

228
    if (widget == NULL)
229 230 231
	return(NULL);

    result = (char *) palloc(60);
232
    sprintf(result, "(%g,%g,%g)",
233
		   widget->center.x, widget->center.y, widget->radius);
234 235 236
    return(result);
}

237
 int
238
pt_in_widget(point, widget)
239
	Point	*point;
240
	WIDGET	*widget;
241 242 243
{
	extern double	point_dt();

244
	return( point_dt(point, &widget->center) < widget->radius );
245 246 247 248
}

#define ABS(X) ((X) > 0 ? (X) : -(X))

249
 int
250 251 252 253 254 255 256
boxarea(box)

BOX *box;

{
	int width, height;

257 258
	width  = ABS(box->high.x - box->low.x);
	height = ABS(box->high.y - box->low.y);
259 260 261
	return (width * height);
}

262
 char *
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
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);
}