PostGIS  3.1.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 1574 of file measures3d.c.

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