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

◆ ptarray_contains_point_partial()

int ptarray_contains_point_partial ( const POINTARRAY pa,
const POINT2D pt,
int  check_closed,
int *  winding_number 
)

Definition at line 1031 of file ptarray.c.

1032{
1033 int wn = 0;
1034 uint32_t i;
1035 double side;
1036 const POINT2D *seg1, *seg2;
1037 double ymin, ymax;
1038
1039 seg1 = getPoint2d_cp(pa, 0);
1040 seg2 = getPoint2d_cp(pa, pa->npoints-1);
1041 if ( check_closed && ! p2d_same(seg1, seg2) )
1042 lwerror("ptarray_contains_point called on unclosed ring");
1043
1044 for ( i=1; i < pa->npoints; i++ )
1045 {
1046 seg2 = getPoint2d_cp(pa, i);
1047
1048 /* Zero length segments are ignored. */
1049 if ( seg1->x == seg2->x && seg1->y == seg2->y )
1050 {
1051 seg1 = seg2;
1052 continue;
1053 }
1054
1055 ymin = FP_MIN(seg1->y, seg2->y);
1056 ymax = FP_MAX(seg1->y, seg2->y);
1057
1058 /* Only test segments in our vertical range */
1059 if ( pt->y > ymax || pt->y < ymin )
1060 {
1061 seg1 = seg2;
1062 continue;
1063 }
1064
1065 side = lw_segment_side(seg1, seg2, pt);
1066
1067 /*
1068 * A point on the boundary of a ring is not contained.
1069 * WAS: if (fabs(side) < 1e-12), see #852
1070 */
1071 if ( (side == 0) && lw_pt_in_seg(pt, seg1, seg2) )
1072 {
1073 return LW_BOUNDARY;
1074 }
1075
1076 /*
1077 * If the point is to the left of the line, and it's rising,
1078 * then the line is to the right of the point and
1079 * circling counter-clockwise, so increment.
1080 */
1081 if ( (side < 0) && (seg1->y <= pt->y) && (pt->y < seg2->y) )
1082 {
1083 wn++;
1084 }
1085
1086 /*
1087 * If the point is to the right of the line, and it's falling,
1088 * then the line is to the right of the point and circling
1089 * clockwise, so decrement.
1090 */
1091 else if ( (side > 0) && (seg2->y <= pt->y) && (pt->y < seg1->y) )
1092 {
1093 wn--;
1094 }
1095
1096 seg1 = seg2;
1097 }
1098
1099 /* Sent out the winding number for calls that are building on this as a primitive */
1100 if ( winding_number )
1101 *winding_number = wn;
1102
1103 /* Outside */
1104 if (wn == 0)
1105 {
1106 return LW_OUTSIDE;
1107 }
1108
1109 /* Inside */
1110 return LW_INSIDE;
1111}
#define LW_INSIDE
Constants for point-in-polygon return values.
#define LW_BOUNDARY
#define FP_MAX(A, B)
#define FP_MIN(A, B)
int lw_pt_in_seg(const POINT2D *P, const POINT2D *A1, const POINT2D *A2)
Returns true if P is between A1/A2.
#define LW_OUTSIDE
int lw_segment_side(const POINT2D *p1, const POINT2D *p2, const POINT2D *q)
lw_segment_side()
Definition lwalgorithm.c:70
int p2d_same(const POINT2D *p1, const POINT2D *p2)
Definition lwalgorithm.c:57
void void lwerror(const char *fmt,...) __attribute__((format(printf
Write a notice out to the error handler.
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:97
double y
Definition liblwgeom.h:390
double x
Definition liblwgeom.h:390
uint32_t npoints
Definition liblwgeom.h:427

References FP_MAX, FP_MIN, getPoint2d_cp(), LW_BOUNDARY, LW_INSIDE, LW_OUTSIDE, lw_pt_in_seg(), lw_segment_side(), lwerror(), POINTARRAY::npoints, p2d_same(), POINT2D::x, and POINT2D::y.

Referenced by _lwt_CheckEdgeCrossing(), _lwt_SplitAllEdgesToNewNode(), and lwt_ChangeEdgeGeom().

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