Skip to content

Commit cf5dc33

Browse files
committed
path_inter, path_distance, path_length, dist_ppath now do the right
things with closed paths --- ie, include the closing line segment in their calculations. Per bug report from Curtis Barrett 9-Oct-01.
1 parent 58dc94a commit cf5dc33

File tree

1 file changed

+94
-22
lines changed

1 file changed

+94
-22
lines changed

src/backend/utils/adt/geo_ops.c

Lines changed: 94 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.58 2001/03/22 03:59:50 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.59 2001/10/13 17:40:24 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -948,7 +948,7 @@ line_construct_pts(LINE *line, Point *pt1, Point *pt2)
948948
}
949949
else if (FPeq(pt1->y, pt2->y))
950950
{ /* horizontal */
951-
/* use "x = C" */
951+
/* use "y = C" */
952952
line->A = 0;
953953
line->B = -1;
954954
line->C = pt1->y;
@@ -1376,6 +1376,9 @@ path_inter(PG_FUNCTION_ARGS)
13761376
LSEG seg1,
13771377
seg2;
13781378

1379+
if (p1->npts <= 0 || p2->npts <= 0)
1380+
PG_RETURN_BOOL(false);
1381+
13791382
b1.high.x = b1.low.x = p1->p[0].x;
13801383
b1.high.y = b1.low.y = p1->p[0].y;
13811384
for (i = 1; i < p1->npts; i++)
@@ -1398,12 +1401,34 @@ path_inter(PG_FUNCTION_ARGS)
13981401
PG_RETURN_BOOL(false);
13991402

14001403
/* pairwise check lseg intersections */
1401-
for (i = 0; i < p1->npts - 1; i++)
1404+
for (i = 0; i < p1->npts; i++)
14021405
{
1403-
for (j = 0; j < p2->npts - 1; j++)
1406+
int iprev;
1407+
1408+
if (i > 0)
1409+
iprev = i-1;
1410+
else
14041411
{
1405-
statlseg_construct(&seg1, &p1->p[i], &p1->p[i + 1]);
1406-
statlseg_construct(&seg2, &p2->p[j], &p2->p[j + 1]);
1412+
if (!p1->closed)
1413+
continue;
1414+
iprev = p1->npts-1; /* include the closure segment */
1415+
}
1416+
1417+
for (j = 0; j < p2->npts; j++)
1418+
{
1419+
int jprev;
1420+
1421+
if (j > 0)
1422+
jprev = j-1;
1423+
else
1424+
{
1425+
if (!p2->closed)
1426+
continue;
1427+
jprev = p2->npts-1; /* include the closure segment */
1428+
}
1429+
1430+
statlseg_construct(&seg1, &p1->p[iprev], &p1->p[i]);
1431+
statlseg_construct(&seg2, &p2->p[jprev], &p2->p[j]);
14071432
if (lseg_intersect_internal(&seg1, &seg2))
14081433
PG_RETURN_BOOL(true);
14091434
}
@@ -1422,20 +1447,42 @@ path_distance(PG_FUNCTION_ARGS)
14221447
{
14231448
PATH *p1 = PG_GETARG_PATH_P(0);
14241449
PATH *p2 = PG_GETARG_PATH_P(1);
1425-
bool have_min = false;
14261450
float8 min = 0.0; /* initialize to keep compiler quiet */
1451+
bool have_min = false;
14271452
float8 tmp;
14281453
int i,
14291454
j;
14301455
LSEG seg1,
14311456
seg2;
14321457

1433-
for (i = 0; i < p1->npts - 1; i++)
1458+
for (i = 0; i < p1->npts; i++)
14341459
{
1435-
for (j = 0; j < p2->npts - 1; j++)
1460+
int iprev;
1461+
1462+
if (i > 0)
1463+
iprev = i-1;
1464+
else
14361465
{
1437-
statlseg_construct(&seg1, &p1->p[i], &p1->p[i + 1]);
1438-
statlseg_construct(&seg2, &p2->p[j], &p2->p[j + 1]);
1466+
if (!p1->closed)
1467+
continue;
1468+
iprev = p1->npts-1; /* include the closure segment */
1469+
}
1470+
1471+
for (j = 0; j < p2->npts; j++)
1472+
{
1473+
int jprev;
1474+
1475+
if (j > 0)
1476+
jprev = j-1;
1477+
else
1478+
{
1479+
if (!p2->closed)
1480+
continue;
1481+
jprev = p2->npts-1; /* include the closure segment */
1482+
}
1483+
1484+
statlseg_construct(&seg1, &p1->p[iprev], &p1->p[i]);
1485+
statlseg_construct(&seg2, &p2->p[jprev], &p2->p[j]);
14391486

14401487
tmp = DatumGetFloat8(DirectFunctionCall2(lseg_distance,
14411488
LsegPGetDatum(&seg1),
@@ -1463,12 +1510,24 @@ Datum
14631510
path_length(PG_FUNCTION_ARGS)
14641511
{
14651512
PATH *path = PG_GETARG_PATH_P(0);
1466-
float8 result;
1513+
float8 result = 0.0;
14671514
int i;
14681515

1469-
result = 0.0;
1470-
for (i = 0; i < (path->npts - 1); i++)
1471-
result += point_dt(&path->p[i], &path->p[i + 1]);
1516+
for (i = 0; i < path->npts; i++)
1517+
{
1518+
int iprev;
1519+
1520+
if (i > 0)
1521+
iprev = i-1;
1522+
else
1523+
{
1524+
if (!path->closed)
1525+
continue;
1526+
iprev = path->npts-1; /* include the closure segment */
1527+
}
1528+
1529+
result += point_dt(&path->p[iprev], &path->p[i]);
1530+
}
14721531

14731532
PG_RETURN_FLOAT8(result);
14741533
}
@@ -2133,17 +2192,18 @@ dist_ppath(PG_FUNCTION_ARGS)
21332192
Point *pt = PG_GETARG_POINT_P(0);
21342193
PATH *path = PG_GETARG_PATH_P(1);
21352194
float8 result = 0.0; /* keep compiler quiet */
2195+
bool have_min = false;
21362196
float8 tmp;
21372197
int i;
21382198
LSEG lseg;
21392199

21402200
switch (path->npts)
21412201
{
2142-
/* no points in path? then result is undefined... */
21432202
case 0:
2203+
/* no points in path? then result is undefined... */
21442204
PG_RETURN_NULL();
2145-
/* one point in path? then get distance between two points... */
21462205
case 1:
2206+
/* one point in path? then get distance between two points... */
21472207
result = point_dt(pt, &path->p[0]);
21482208
break;
21492209
default:
@@ -2154,12 +2214,26 @@ dist_ppath(PG_FUNCTION_ARGS)
21542214
* the distance from a point to a path is the smallest
21552215
* distance from the point to any of its constituent segments.
21562216
*/
2157-
for (i = 0; i < path->npts - 1; i++)
2217+
for (i = 0; i < path->npts; i++)
21582218
{
2159-
statlseg_construct(&lseg, &path->p[i], &path->p[i + 1]);
2219+
int iprev;
2220+
2221+
if (i > 0)
2222+
iprev = i-1;
2223+
else
2224+
{
2225+
if (!path->closed)
2226+
continue;
2227+
iprev = path->npts-1; /* include the closure segment */
2228+
}
2229+
2230+
statlseg_construct(&lseg, &path->p[iprev], &path->p[i]);
21602231
tmp = dist_ps_internal(pt, &lseg);
2161-
if (i == 0 || tmp < result)
2232+
if (!have_min || tmp < result)
2233+
{
21622234
result = tmp;
2235+
have_min = true;
2236+
}
21632237
}
21642238
break;
21652239
}
@@ -2824,8 +2898,6 @@ on_pb(PG_FUNCTION_ARGS)
28242898
* but not cross.
28252899
* (we can do p-in-p in lg(n), but it takes preprocessing)
28262900
*/
2827-
#define NEXT(A) (((A)+1) % path->npts) /* cyclic "i+1" */
2828-
28292901
Datum
28302902
on_ppath(PG_FUNCTION_ARGS)
28312903
{

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy