Commit 4ae6967f authored by Bruce Momjian's avatar Bruce Momjian

Remove copied comments from geo_ops.c source file and replace with new

comments, and cleanup functions.  Remove copyright that is no longer
relevant.
parent 37fc8a66
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/geo_ops.c,v 1.95 2007/02/27 23:48:08 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/adt/geo_ops.c,v 1.96 2007/03/05 23:29:14 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -5063,128 +5063,126 @@ poly_circle(PG_FUNCTION_ARGS) ...@@ -5063,128 +5063,126 @@ poly_circle(PG_FUNCTION_ARGS)
***********************************************************************/ ***********************************************************************/
/* /*
* Test to see if the point is inside the polygon. * Test to see if the point is inside the polygon, returns 1/0, or 2 if
* Code adapted from integer-based routines in WN: A Server for the HTTP * the point is on the polygon.
* Code adapted but not copied from integer-based routines in WN: A
* Server for the HTTP
* version 1.15.1, file wn/image.c * version 1.15.1, file wn/image.c
* GPL Copyright (C) 1995 by John Franks
* http://hopf.math.northwestern.edu/index.html * http://hopf.math.northwestern.edu/index.html
* Description of algorithm: http://www.linuxjournal.com/article/2197 * Description of algorithm: http://www.linuxjournal.com/article/2197
* http://www.linuxjournal.com/article/2029
*/ */
#define HIT_IT INT_MAX #define POINT_ON_POLYGON INT_MAX
static int static int
point_inside(Point *p, int npts, Point *plist) point_inside(Point *p, int npts, Point *plist)
{ {
double x0, double x0,
y0; y0;
double px, double prev_x,
py; prev_y;
int i; int i = 0;
double x, double x,
y; y;
int cross, int cross, total_cross = 0;
crossnum;
/*
* We calculate crossnum, which is twice the crossing number of a
* ray from the origin parallel to the positive X axis.
* A coordinate change is made to move the test point to the origin.
* Then the function lseg_crossing() is called to calculate the crossnum of
* one segment of the translated polygon with the ray which is the
* positive X-axis.
*/
crossnum = 0;
i = 0;
if (npts <= 0) if (npts <= 0)
return 0; return 0;
/* compute first polygon point relative to single point */
x0 = plist[0].x - p->x; x0 = plist[0].x - p->x;
y0 = plist[0].y - p->y; y0 = plist[0].y - p->y;
px = x0; prev_x = x0;
py = y0; prev_y = y0;
/* loop over polygon points and aggregate total_cross */
for (i = 1; i < npts; i++) for (i = 1; i < npts; i++)
{ {
/* compute next polygon point relative to single point */
x = plist[i].x - p->x; x = plist[i].x - p->x;
y = plist[i].y - p->y; y = plist[i].y - p->y;
if ((cross = lseg_crossing(x, y, px, py)) == HIT_IT) /* compute previous to current point crossing */
if ((cross = lseg_crossing(x, y, prev_x, prev_y)) == POINT_ON_POLYGON)
return 2; return 2;
crossnum += cross; total_cross += cross;
px = x; prev_x = x;
py = y; prev_y = y;
} }
if ((cross = lseg_crossing(x0, y0, px, py)) == HIT_IT)
/* now do the first point */
if ((cross = lseg_crossing(x0, y0, prev_x, prev_y)) == POINT_ON_POLYGON)
return 2; return 2;
crossnum += cross; total_cross += cross;
if (crossnum != 0)
if (total_cross != 0)
return 1; return 1;
return 0; return 0;
} }
/* lseg_crossing() /* lseg_crossing()
* The function lseg_crossing() returns +2, or -2 if the segment from (x,y) * Returns +/-2 if line segment crosses the positive X-axis in a +/- direction.
* to previous (x,y) crosses the positive X-axis positively or negatively. * Returns +/-1 if one point is on the positive X-axis.
* It returns +1 or -1 if one endpoint is on this ray, or 0 if both are. * Returns 0 if both points are on the positive X-axis, or there is no crossing.
* It returns 0 if the ray and the segment don't intersect. * Returns POINT_ON_POLYGON if the segment contains (0,0).
* It returns HIT_IT if the segment contains (0,0) * Wow, that is one confusing API, but it is used above, and when summed,
* can tell is if a point is in a polygon.
*/ */
static int static int
lseg_crossing(double x, double y, double px, double py) lseg_crossing(double x, double y, double prev_x, double prev_y)
{ {
double z; double z;
int sgn; int y_sign;
/* If (px,py) = (0,0) and not first call we have already sent HIT_IT */
if (FPzero(y)) if (FPzero(y))
{ { /* y == 0, on X axis */
if (FPzero(x)) if (FPzero(x)) /* (x,y) is (0,0)? */
{ return POINT_ON_POLYGON;
return HIT_IT;
}
else if (FPgt(x, 0)) else if (FPgt(x, 0))
{ { /* x > 0 */
if (FPzero(py)) if (FPzero(prev_y)) /* y and prev_y are zero */
return FPgt(px, 0) ? 0 : HIT_IT; /* prev_x > 0? */
return FPlt(py, 0) ? 1 : -1; return FPgt(prev_x, 0) ? 0 : POINT_ON_POLYGON;
return FPlt(prev_y, 0) ? 1 : -1;
} }
else else
{ /* x < 0 */ { /* x < 0, x not on positive X axis */
if (FPzero(py)) if (FPzero(prev_y))
return FPlt(px, 0) ? 0 : HIT_IT; /* prev_x < 0? */
return FPlt(prev_x, 0) ? 0 : POINT_ON_POLYGON;
return 0; return 0;
} }
} }
/* Now we know y != 0; set sgn to sign of y */
sgn = (FPgt(y, 0) ? 1 : -1);
if (FPzero(py))
return FPlt(px, 0) ? 0 : sgn;
if (FPgt((sgn * py), 0))
{ /* y and py have same sign */
return 0;
}
else else
{ /* y and py have opposite signs */ { /* y != 0 */
if (FPge(x, 0) && FPgt(px, 0)) /* compute y crossing direction from previous point */
return 2 * sgn; y_sign = FPgt(y, 0) ? 1 : -1;
if (FPlt(x, 0) && FPle(px, 0))
return 0; if (FPzero(prev_y))
/* previous point was on X axis, so new point is either off or on */
z = (x - px) * y - (y - py) * x; return FPlt(prev_x, 0) ? 0 : y_sign;
if (FPzero(z)) else if (FPgt(y_sign * prev_y, 0))
return HIT_IT; /* both above or below X axis */
return FPgt((sgn * z), 0) ? 0 : 2 * sgn; return 0; /* same sign */
else
{ /* y and prev_y cross X-axis */
if (FPge(x, 0) && FPgt(prev_x, 0))
/* both non-negative so cross positive X-axis */
return 2 * y_sign;
if (FPlt(x, 0) && FPle(prev_x, 0))
/* both non-positive so do not cross positive X-axis */
return 0;
/* x and y cross axises, see URL above point_inside() */
z = (x - prev_x) * y - (y - prev_y) * x;
if (FPzero(z))
return POINT_ON_POLYGON;
return FPgt((y_sign * z), 0) ? 0 : 2 * y_sign;
}
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment