PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ 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: