PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ point_in_ring()

static int point_in_ring ( POINTARRAY pts,
const POINT2D point 
)
static

Definition at line 805 of file lwgeom_functions_analytic.c.

References determineSide(), FP_CONTAINS_BOTTOM, getPoint2d_cp(), isOnSegment(), POINTARRAY::npoints, POINT2D::x, and POINT2D::y.

Referenced by point_in_multipolygon(), and point_in_polygon().

806 {
807  int wn = 0;
808  int i;
809  double side;
810  const POINT2D* seg1;
811  const POINT2D* seg2;
812 
813  POSTGIS_DEBUG(2, "point_in_ring called.");
814 
815  seg2 = getPoint2d_cp(pts, 0);
816  for (i=0; i<pts->npoints-1; i++)
817  {
818  seg1 = seg2;
819  seg2 = getPoint2d_cp(pts, i+1);
820 
821  side = determineSide(seg1, seg2, point);
822 
823  POSTGIS_DEBUGF(3, "segment: (%.8f, %.8f),(%.8f, %.8f)", seg1->x, seg1->y, seg2->x, seg2->y);
824  POSTGIS_DEBUGF(3, "side result: %.8f", side);
825  POSTGIS_DEBUGF(3, "counterclockwise wrap %d, clockwise wrap %d", FP_CONTAINS_BOTTOM(seg1->y, point->y, seg2->y), FP_CONTAINS_BOTTOM(seg2->y, point->y, seg1->y));
826 
827  /* zero length segments are ignored. */
828  if ((seg2->x == seg1->x) && (seg2->y == seg1->y))
829  {
830  POSTGIS_DEBUG(3, "segment is zero length... ignoring.");
831 
832  continue;
833  }
834 
835  /* a point on the boundary of a ring is not contained. */
836  /* WAS: if (fabs(side) < 1e-12), see #852 */
837  if (side == 0.0)
838  {
839  if (isOnSegment(seg1, seg2, point) == 1)
840  {
841  POSTGIS_DEBUGF(3, "point on ring boundary between points %d, %d", i, i+1);
842 
843  return 0;
844  }
845  }
846 
847  /*
848  * If the point is to the left of the line, and it's rising,
849  * then the line is to the right of the point and
850  * circling counter-clockwise, so incremement.
851  */
852  if ((seg1->y <= point->y) && (point->y < seg2->y) && (side > 0))
853  {
854  POSTGIS_DEBUG(3, "incrementing winding number.");
855 
856  ++wn;
857  }
858  /*
859  * If the point is to the right of the line, and it's falling,
860  * then the line is to the right of the point and circling
861  * clockwise, so decrement.
862  */
863  else if ((seg2->y <= point->y) && (point->y < seg1->y) && (side < 0))
864  {
865  POSTGIS_DEBUG(3, "decrementing winding number.");
866 
867  --wn;
868  }
869  }
870 
871  POSTGIS_DEBUGF(3, "winding number %d", wn);
872 
873  if (wn == 0)
874  return -1;
875  return 1;
876 }
int npoints
Definition: liblwgeom.h:371
double x
Definition: liblwgeom.h:328
const POINT2D * getPoint2d_cp(const POINTARRAY *pa, int n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from...
Definition: lwgeom_api.c:373
double y
Definition: liblwgeom.h:328
static int isOnSegment(const POINT2D *seg1, const POINT2D *seg2, const POINT2D *point)
static double determineSide(const POINT2D *seg1, const POINT2D *seg2, const POINT2D *point)
#define FP_CONTAINS_BOTTOM(A, X, B)
Here is the call graph for this function:
Here is the caller graph for this function: