PostGIS  3.4.0dev-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 1564 of file measures3d.c.

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