PostGIS  3.7.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 1573 of file measures3d.c.

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