PostGIS 3.0.6dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ point_in_ring()

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

Definition at line 818 of file lwgeom_functions_analytic.c.

819{
820 int wn = 0;
821 uint32_t i;
822 double side;
823 const POINT2D* seg1;
824 const POINT2D* seg2;
825
826 POSTGIS_DEBUG(2, "point_in_ring called.");
827
828 seg2 = getPoint2d_cp(pts, 0);
829 for (i=0; i<pts->npoints-1; i++)
830 {
831 seg1 = seg2;
832 seg2 = getPoint2d_cp(pts, i+1);
833
834 side = determineSide(seg1, seg2, point);
835
836 POSTGIS_DEBUGF(3, "segment: (%.8f, %.8f),(%.8f, %.8f)", seg1->x, seg1->y, seg2->x, seg2->y);
837 POSTGIS_DEBUGF(3, "side result: %.8f", side);
838 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));
839
840 /* zero length segments are ignored. */
841 if ((seg2->x == seg1->x) && (seg2->y == seg1->y))
842 {
843 POSTGIS_DEBUG(3, "segment is zero length... ignoring.");
844
845 continue;
846 }
847
848 /* a point on the boundary of a ring is not contained. */
849 /* WAS: if (fabs(side) < 1e-12), see #852 */
850 if (side == 0.0)
851 {
852 if (isOnSegment(seg1, seg2, point) == 1)
853 {
854 POSTGIS_DEBUGF(3, "point on ring boundary between points %d, %d", i, i+1);
855
856 return 0;
857 }
858 }
859
860 /*
861 * If the point is to the left of the line, and it's rising,
862 * then the line is to the right of the point and
863 * circling counter-clockwise, so increment.
864 */
865 if ((seg1->y <= point->y) && (point->y < seg2->y) && (side > 0))
866 {
867 POSTGIS_DEBUG(3, "incrementing winding number.");
868
869 ++wn;
870 }
871 /*
872 * If the point is to the right of the line, and it's falling,
873 * then the line is to the right of the point and circling
874 * clockwise, so decrement.
875 */
876 else if ((seg2->y <= point->y) && (point->y < seg1->y) && (side < 0))
877 {
878 POSTGIS_DEBUG(3, "decrementing winding number.");
879
880 --wn;
881 }
882 }
883
884 POSTGIS_DEBUGF(3, "winding number %d", wn);
885
886 if (wn == 0)
887 return -1;
888 return 1;
889}
#define FP_CONTAINS_BOTTOM(A, X, B)
static int isOnSegment(const POINT2D *seg1, const POINT2D *seg2, const POINT2D *point)
static double determineSide(const POINT2D *seg1, const POINT2D *seg2, const POINT2D *point)
static const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
Definition lwinline.h:91
double y
Definition liblwgeom.h:376
double x
Definition liblwgeom.h:376
uint32_t npoints
Definition liblwgeom.h:413

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

Referenced by point_in_multipolygon(), and point_in_polygon().

Here is the call graph for this function:
Here is the caller graph for this function: