PostGIS  2.5.7dev-r@@SVN_REVISION@@

◆ pt_in_ring_2d()

int pt_in_ring_2d ( const POINT2D p,
const POINTARRAY ring 
)

Definition at line 281 of file lwalgorithm.c.

282 {
283  int cn = 0; /* the crossing number counter */
284  uint32_t i;
285  const POINT2D *v1, *v2;
286  const POINT2D *first, *last;
287 
288  first = getPoint2d_cp(ring, 0);
289  last = getPoint2d_cp(ring, ring->npoints-1);
290  if ( memcmp(first, last, sizeof(POINT2D)) )
291  {
292  lwerror("pt_in_ring_2d: V[n] != V[0] (%g %g != %g %g)",
293  first->x, first->y, last->x, last->y);
294  return LW_FALSE;
295 
296  }
297 
298  LWDEBUGF(2, "pt_in_ring_2d called with point: %g %g", p->x, p->y);
299  /* printPA(ring); */
300 
301  /* loop through all edges of the polygon */
302  v1 = getPoint2d_cp(ring, 0);
303  for (i=0; i<ring->npoints-1; i++)
304  {
305  double vt;
306  v2 = getPoint2d_cp(ring, i+1);
307 
308  /* edge from vertex i to vertex i+1 */
309  if
310  (
311  /* an upward crossing */
312  ((v1->y <= p->y) && (v2->y > p->y))
313  /* a downward crossing */
314  || ((v1->y > p->y) && (v2->y <= p->y))
315  )
316  {
317 
318  vt = (double)(p->y - v1->y) / (v2->y - v1->y);
319 
320  /* P->x <intersect */
321  if (p->x < v1->x + vt * (v2->x - v1->x))
322  {
323  /* a valid crossing of y=p->y right of p->x */
324  ++cn;
325  }
326  }
327  v1 = v2;
328  }
329 
330  LWDEBUGF(3, "pt_in_ring_2d returning %d", cn&1);
331 
332  return (cn&1); /* 0 if even (out), and 1 if odd (in) */
333 }
#define LW_FALSE
Definition: liblwgeom.h:77
const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
Definition: lwgeom_api.c:374
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:88
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
double y
Definition: liblwgeom.h:331
double x
Definition: liblwgeom.h:331
uint32_t npoints
Definition: liblwgeom.h:374
unsigned int uint32_t
Definition: uthash.h:78