Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 70c4c57

Browse files
author
Thomas G. Lockhart
committed
Make a few line routines visible.
Incorporate patches from Gautam for line/point intersection.
1 parent 8e602a3 commit 70c4c57

File tree

1 file changed

+157
-41
lines changed

1 file changed

+157
-41
lines changed

src/backend/utils/adt/geo_ops.c

+157-41
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.31 1998/02/26 04:37:08 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.32 1998/05/09 22:39:55 thomas Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -42,11 +42,6 @@ static double box_wd(BOX *box);
4242
static double circle_ar(CIRCLE *circle);
4343
static CIRCLE *circle_copy(CIRCLE *circle);
4444
static LINE *line_construct_pm(Point *pt, double m);
45-
static bool line_horizontal(LINE *line);
46-
static Point *line_interpt(LINE *l1, LINE *l2);
47-
static bool line_intersect(LINE *l1, LINE *l2);
48-
static bool line_parallel(LINE *l1, LINE *l2);
49-
static bool line_vertical(LINE *line);
5045
static double lseg_dt(LSEG *l1, LSEG *l2);
5146
static void make_bound_box(POLYGON *poly);
5247
static PATH *path_copy(PATH *path);
@@ -63,7 +58,6 @@ static char *path_encode(bool closed, int npts, Point *pt);
6358
static void statlseg_construct(LSEG *lseg, Point *pt1, Point *pt2);
6459
static double box_ar(BOX *box);
6560
static Point *interpt_sl(LSEG *lseg, LINE *line);
66-
static LINE *line_construct_pp(Point *pt1, Point *pt2);
6761

6862

6963
/*
@@ -776,12 +770,105 @@ box_diagonal(BOX *box)
776770
**
777771
***********************************************************************/
778772

773+
LINE *
774+
line_in(char *str)
775+
{
776+
LINE *line;
777+
778+
#if LINEDEBUG
779+
LSEG lseg;
780+
int isopen;
781+
char *s;
782+
#endif
783+
784+
if (!PointerIsValid(str))
785+
elog(ERROR, " Bad (null) line external representation", NULL);
786+
787+
#if LINEDEBUG
788+
if ((!path_decode(TRUE, 2, str, &isopen, &s, &(lseg.p[0])))
789+
|| (*s != '\0'))
790+
elog(ERROR, "Bad line external representation '%s'", str);
791+
792+
line = line_construct_pp(&(lseg.p[0]), &(lseg.p[1]));
793+
#else
794+
elog(ERROR, "line not yet implemented");
795+
line = NULL;
796+
#endif
797+
798+
return (line);
799+
} /* line_in() */
800+
801+
802+
char *
803+
line_out(LINE *line)
804+
{
805+
char *result;
806+
807+
if (!PointerIsValid(line))
808+
return (NULL);
809+
810+
#if LINEDEBUG
811+
if (FPzero(line->B))
812+
{ /* vertical */
813+
/* use "x = C" */
814+
result->A = -1;
815+
result->B = 0;
816+
result->C = pt1->x;
817+
#ifdef GEODEBUG
818+
printf("line_construct_pp- line is vertical\n");
819+
#endif
820+
#if FALSE
821+
result->m = DBL_MAX;
822+
#endif
823+
824+
}
825+
else if (FPzero(line->A))
826+
{ /* horizontal */
827+
/* use "x = C" */
828+
result->A = 0;
829+
result->B = -1;
830+
result->C = pt1->y;
831+
#ifdef GEODEBUG
832+
printf("line_construct_pp- line is horizontal\n");
833+
#endif
834+
#if FALSE
835+
result->m = 0.0;
836+
#endif
837+
838+
}
839+
else
840+
{
841+
}
842+
843+
if (line_horizontal(line))
844+
{
845+
}
846+
else if (line_vertical(line))
847+
{
848+
}
849+
else
850+
{
851+
}
852+
853+
return (path_encode(TRUE, 2, (Point *) &(ls->p[0])));
854+
#else
855+
elog(ERROR, "line not yet implemented");
856+
result = NULL;
857+
#endif
858+
859+
return (result);
860+
} /* line_out() */
861+
862+
779863
/*----------------------------------------------------------
780864
* Conversion routines from one line formula to internal.
781865
* Internal form: Ax+By+C=0
782866
*---------------------------------------------------------*/
783867

784-
static LINE * /* point-slope */
868+
/* line_construct_pm()
869+
* point-slope
870+
*/
871+
LINE *
785872
line_construct_pm(Point *pt, double m)
786873
{
787874
LINE *result = palloc(sizeof(LINE));
@@ -799,7 +886,10 @@ line_construct_pm(Point *pt, double m)
799886
} /* line_construct_pm() */
800887

801888

802-
static LINE * /* two points */
889+
/* line_construct_pp()
890+
* two points
891+
*/
892+
LINE *
803893
line_construct_pp(Point *pt1, Point *pt2)
804894
{
805895
LINE *result = palloc(sizeof(LINE));
@@ -857,13 +947,13 @@ line_construct_pp(Point *pt1, Point *pt2)
857947
* Relative position routines.
858948
*---------------------------------------------------------*/
859949

860-
static bool
950+
bool
861951
line_intersect(LINE *l1, LINE *l2)
862952
{
863953
return (!line_parallel(l1, l2));
864954
}
865955

866-
static bool
956+
bool
867957
line_parallel(LINE *l1, LINE *l2)
868958
{
869959
#if FALSE
@@ -877,7 +967,6 @@ line_parallel(LINE *l1, LINE *l2)
877967
return (FPeq(l2->A, l1->A * (l2->B / l1->B)));
878968
} /* line_parallel() */
879969

880-
#ifdef NOT_USED
881970
bool
882971
line_perp(LINE *l1, LINE *l2)
883972
{
@@ -899,9 +988,7 @@ line_perp(LINE *l1, LINE *l2)
899988
return (FPeq(((l1->A * l2->B) / (l1->B * l2->A)), -1.0));
900989
} /* line_perp() */
901990

902-
#endif
903-
904-
static bool
991+
bool
905992
line_vertical(LINE *line)
906993
{
907994
#if FALSE
@@ -910,7 +997,7 @@ line_vertical(LINE *line)
910997
return (FPzero(line->B));
911998
} /* line_vertical() */
912999

913-
static bool
1000+
bool
9141001
line_horizontal(LINE *line)
9151002
{
9161003
#if FALSE
@@ -919,7 +1006,6 @@ line_horizontal(LINE *line)
9191006
return (FPzero(line->A));
9201007
} /* line_horizontal() */
9211008

922-
#ifdef NOT_USED
9231009
bool
9241010
line_eq(LINE *l1, LINE *l2)
9251011
{
@@ -939,13 +1025,15 @@ line_eq(LINE *l1, LINE *l2)
9391025
FPeq(l1->C, k * l2->C));
9401026
}
9411027

942-
#endif
9431028

9441029
/*----------------------------------------------------------
9451030
* Line arithmetic routines.
9461031
*---------------------------------------------------------*/
9471032

948-
double * /* distance between l1, l2 */
1033+
/* line_distance()
1034+
* Distance between two lines.
1035+
*/
1036+
double *
9491037
line_distance(LINE *l1, LINE *l2)
9501038
{
9511039
double *result = palloc(sizeof(double));
@@ -970,7 +1058,7 @@ line_distance(LINE *l1, LINE *l2)
9701058
/* line_interpt()
9711059
* Point where two lines l1, l2 intersect (if any)
9721060
*/
973-
static Point *
1061+
Point *
9741062
line_interpt(LINE *l1, LINE *l2)
9751063
{
9761064
Point *result;
@@ -2266,6 +2354,7 @@ close_pl(Point *pt, LINE *line)
22662354
*
22672355
* Some tricky code here, relying on boolean expressions
22682356
* evaluating to only zero or one to use as an array index.
2357+
* bug fixes by gthaker@atl.lmco.com; May 1, 98
22692358
*/
22702359
Point *
22712360
close_ps(Point *pt, LSEG *lseg)
@@ -2276,26 +2365,31 @@ close_ps(Point *pt, LSEG *lseg)
22762365
int xh,
22772366
yh;
22782367

2368+
2369+
/* fprintf(stderr,"close_sp:pt->x %f pt->y %f\nlseg(0).x %f lseg(0).y %f lseg(1).x %f lseg(1).y %f\n", */
2370+
/* pt->x, pt->y, lseg->p[0].x, lseg->p[0].y, lseg->p[1].x, lseg->p[1].y); */
2371+
22792372
result = NULL;
22802373
xh = lseg->p[0].x < lseg->p[1].x;
22812374
yh = lseg->p[0].y < lseg->p[1].y;
2282-
if (pt->x < lseg->p[!xh].x)
2283-
result = point_copy(&lseg->p[!xh]);
2284-
else if (pt->x > lseg->p[xh].x)
2285-
result = point_copy(&lseg->p[xh]);
2286-
else if (pt->y < lseg->p[!yh].y)
2287-
result = point_copy(&lseg->p[!yh]);
2288-
else if (pt->y > lseg->p[yh].y)
2289-
result = point_copy(&lseg->p[yh]);
2290-
if (result != NULL)
2291-
return (result);
2375+
/* !xh (or !yh) is the index of lower x( or y) end point of lseg */
22922376

22932377
/* vertical segment? */
22942378
if (lseg_vertical(lseg))
22952379
{
22962380
#ifdef GEODEBUG
22972381
printf("close_ps- segment is vertical\n");
22982382
#endif
2383+
/* first check if point is below or above the entire lseg. */
2384+
if (pt->y < lseg->p[!yh].y)
2385+
result = point_copy(&lseg->p[!yh]); /* below the lseg */
2386+
else if (pt->y > lseg->p[yh].y)
2387+
result = point_copy(&lseg->p[yh]); /* above the lseg */
2388+
if (result != NULL)
2389+
return (result);
2390+
2391+
/* point lines along (to left or right) of the vertical lseg. */
2392+
22992393
result = palloc(sizeof(*result));
23002394
result->x = lseg->p[0].x;
23012395
result->y = pt->y;
@@ -2306,15 +2400,47 @@ close_ps(Point *pt, LSEG *lseg)
23062400
#ifdef GEODEBUG
23072401
printf("close_ps- segment is horizontal\n");
23082402
#endif
2403+
/* first check if point is left or right of the entire lseg. */
2404+
if (pt->x < lseg->p[!xh].x)
2405+
result = point_copy(&lseg->p[!xh]); /* left of the lseg */
2406+
else if (pt->x > lseg->p[xh].x)
2407+
result = point_copy(&lseg->p[xh]); /* right of the lseg */
2408+
if (result != NULL)
2409+
return (result);
2410+
2411+
/* point lines along (at top or below) the horiz. lseg. */
23092412
result = palloc(sizeof(*result));
23102413
result->x = pt->x;
23112414
result->y = lseg->p[0].y;
23122415
return (result);
23132416
}
23142417

2418+
/* vert. and horiz. cases are down, now check if the closest
2419+
* point is one of the end points or someplace on the lseg. */
2420+
2421+
/* TODO: Ask if "tmp" should be freed to prevent memory leak */
2422+
23152423
invm = -1.0 / point_sl(&(lseg->p[0]), &(lseg->p[1]));
2424+
tmp = line_construct_pm(&lseg->p[!yh], invm); /* lower edge of the "band" */
2425+
if (pt->y < (tmp->A*pt->x + tmp->C)) { /* we are below the lower edge */
2426+
result = point_copy(&lseg->p[!yh]); /* below the lseg, take lower end pt */
2427+
/* fprintf(stderr,"below: tmp A %f B %f C %f m %f\n",tmp->A,tmp->B,tmp->C, tmp->m); */
2428+
2429+
return result;
2430+
}
2431+
tmp = line_construct_pm(&lseg->p[yh], invm); /* upper edge of the "band" */
2432+
if (pt->y > (tmp->A*pt->x + tmp->C)) { /* we are below the lower edge */
2433+
result = point_copy(&lseg->p[yh]); /* above the lseg, take higher end pt */
2434+
/* fprintf(stderr,"above: tmp A %f B %f C %f m %f\n",tmp->A,tmp->B,tmp->C, tmp->m); */
2435+
return result;
2436+
}
2437+
2438+
/* at this point the "normal" from point will hit lseg. The closet point
2439+
* will be somewhere on the lseg */
23162440
tmp = line_construct_pm(pt, invm);
2441+
/* fprintf(stderr,"tmp A %f B %f C %f m %f\n",tmp->A,tmp->B,tmp->C, tmp->m); */
23172442
result = interpt_sl(lseg, tmp);
2443+
/* fprintf(stderr,"result.x %f result.y %f\n", result->x, result->y); */
23182444
return (result);
23192445
} /* close_ps() */
23202446

@@ -3309,16 +3435,6 @@ box_div(BOX *box, Point *p)
33093435
} /* box_div() */
33103436

33113437

3312-
/***********************************************************************
3313-
**
3314-
** Routines for 2D lines.
3315-
** Lines are not intended to be used as ADTs per se,
3316-
** but their ops are useful tools for other ADT ops. Thus,
3317-
** there are few relops.
3318-
**
3319-
***********************************************************************/
3320-
3321-
33223438
/***********************************************************************
33233439
**
33243440
** Routines for 2D paths.
@@ -4330,7 +4446,7 @@ box_circle(BOX *box)
43304446
} /* box_circle() */
43314447

43324448

4333-
POLYGON *
4449+
POLYGON *
43344450
circle_poly(int npts, CIRCLE *circle)
43354451
{
43364452
POLYGON *poly;

0 commit comments

Comments
 (0)