PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ pt_in_ring_3d()

int pt_in_ring_3d ( const POINT3DZ p,
const POINTARRAY ring,
PLANE3D plane 
)

pt_in_ring_3d(): crossing number test for a point in a polygon input: p = a point, pa = vertex points of a ring V[n+1] with V[n]=V[0] plane=the plane that the vertex points are lying on returns: 0 = outside, 1 = inside

Our polygons have first and last point the same,

The difference in 3D variant is that we exclude the dimension that faces the plane least. That is the dimension with the highest number in pv

Definition at line 1567 of file measures3d.c.

1568 {
1569 
1570  uint32_t cn = 0; /* the crossing number counter */
1571  uint32_t i;
1572  POINT3DZ v1, v2;
1573 
1574  POINT3DZ first, last;
1575 
1576  getPoint3dz_p(ring, 0, &first);
1577  getPoint3dz_p(ring, ring->npoints - 1, &last);
1578  if (memcmp(&first, &last, sizeof(POINT3DZ)))
1579  {
1580  lwerror("pt_in_ring_3d: V[n] != V[0] (%g %g %g!= %g %g %g)",
1581  first.x,
1582  first.y,
1583  first.z,
1584  last.x,
1585  last.y,
1586  last.z);
1587  return LW_FALSE;
1588  }
1589 
1590  LWDEBUGF(2, "pt_in_ring_3d called with point: %g %g %g", p->x, p->y, p->z);
1591  /* printPA(ring); */
1592 
1593  /* loop through all edges of the polygon */
1594  getPoint3dz_p(ring, 0, &v1);
1595 
1596  if (fabs(plane->pv.z) >= fabs(plane->pv.x) &&
1597  fabs(plane->pv.z) >= fabs(plane->pv.y)) /*If the z vector of the normal vector to the plane is larger than x
1598  and y vector we project the ring to the xy-plane*/
1599  {
1600  for (i = 0; i < ring->npoints - 1; i++)
1601  {
1602  double vt;
1603  getPoint3dz_p(ring, i + 1, &v2);
1604 
1605  /* edge from vertex i to vertex i+1 */
1606  if (
1607  /* an upward crossing */
1608  ((v1.y <= p->y) && (v2.y > p->y))
1609  /* a downward crossing */
1610  || ((v1.y > p->y) && (v2.y <= p->y)))
1611  {
1612 
1613  vt = (double)(p->y - v1.y) / (v2.y - v1.y);
1614 
1615  /* P.x <intersect */
1616  if (p->x < v1.x + vt * (v2.x - v1.x))
1617  {
1618  /* a valid crossing of y=p.y right of p.x */
1619  ++cn;
1620  }
1621  }
1622  v1 = v2;
1623  }
1624  }
1625  else if (fabs(plane->pv.y) >= fabs(plane->pv.x) &&
1626  fabs(plane->pv.y) >= fabs(plane->pv.z)) /*If the y vector of the normal vector to the plane is larger
1627  than x and z vector we project the ring to the xz-plane*/
1628  {
1629  for (i = 0; i < ring->npoints - 1; i++)
1630  {
1631  double vt;
1632  getPoint3dz_p(ring, i + 1, &v2);
1633 
1634  /* edge from vertex i to vertex i+1 */
1635  if (
1636  /* an upward crossing */
1637  ((v1.z <= p->z) && (v2.z > p->z))
1638  /* a downward crossing */
1639  || ((v1.z > p->z) && (v2.z <= p->z)))
1640  {
1641 
1642  vt = (double)(p->z - v1.z) / (v2.z - v1.z);
1643 
1644  /* P.x <intersect */
1645  if (p->x < v1.x + vt * (v2.x - v1.x))
1646  {
1647  /* a valid crossing of y=p.y right of p.x */
1648  ++cn;
1649  }
1650  }
1651  v1 = v2;
1652  }
1653  }
1654  else /*Hopefully we only have the cases where x part of the normal vector is largest left*/
1655  {
1656  for (i = 0; i < ring->npoints - 1; i++)
1657  {
1658  double vt;
1659  getPoint3dz_p(ring, i + 1, &v2);
1660 
1661  /* edge from vertex i to vertex i+1 */
1662  if (
1663  /* an upward crossing */
1664  ((v1.z <= p->z) && (v2.z > p->z))
1665  /* a downward crossing */
1666  || ((v1.z > p->z) && (v2.z <= p->z)))
1667  {
1668 
1669  vt = (double)(p->z - v1.z) / (v2.z - v1.z);
1670 
1671  /* P.x <intersect */
1672  if (p->y < v1.y + vt * (v2.y - v1.y))
1673  {
1674  /* a valid crossing of y=p.y right of p.x */
1675  ++cn;
1676  }
1677  }
1678  v1 = v2;
1679  }
1680  }
1681  LWDEBUGF(3, "pt_in_ring_3d returning %d", cn & 1);
1682 
1683  return (cn & 1); /* 0 if even (out), and 1 if odd (in) */
1684 }
#define LW_FALSE
Definition: liblwgeom.h:108
int getPoint3dz_p(const POINTARRAY *pa, uint32_t n, POINT3DZ *point)
Definition: lwgeom_api.c:215
#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
VECTOR3D pv
Definition: measures3d.h:58
double z
Definition: liblwgeom.h:382
double x
Definition: liblwgeom.h:382
double y
Definition: liblwgeom.h:382
uint32_t npoints
Definition: liblwgeom.h:413
double z
Definition: measures3d.h:52
double x
Definition: measures3d.h:52
double y
Definition: measures3d.h:52

References getPoint3dz_p(), LW_FALSE, LWDEBUGF, lwerror(), POINTARRAY::npoints, PLANE3D::pv, POINT3DZ::x, VECTOR3D::x, POINT3DZ::y, VECTOR3D::y, POINT3DZ::z, and VECTOR3D::z.

Referenced by lw_dist3d_pt_poly(), lw_dist3d_pt_tri(), lw_dist3d_ptarray_poly(), and lw_dist3d_ptarray_tri().

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