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;
1571 uint32_t i;
1573
1575
1578 if (memcmp(&first, &last,
sizeof(
POINT3DZ)))
1579 {
1580 lwerror(
"pt_in_ring_3d: V[n] != V[0] (%g %g %g!= %g %g %g)",
1588 }
1589
1590 LWDEBUGF(2,
"pt_in_ring_3d called with point: %g %g %g", p->
x, p->
y, p->
z);
1591
1592
1593
1595
1596 if (fabs(plane->
pv.
z) >= fabs(plane->
pv.
x) &&
1597 fabs(plane->
pv.
z) >= fabs(plane->
pv.
y))
1598
1599 {
1600 for (i = 0; i < ring->
npoints - 1; i++)
1601 {
1602 double vt;
1604
1605
1606 if (
1607
1608 ((v1.
y <= p->
y) && (v2.
y > p->
y))
1609
1610 || ((v1.
y > p->
y) && (v2.
y <= p->
y)))
1611 {
1612
1613 vt = (double)(p->
y - v1.
y) / (v2.
y - v1.
y);
1614
1615
1616 if (p->
x < v1.
x + vt * (v2.
x - v1.
x))
1617 {
1618
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))
1627
1628 {
1629 for (i = 0; i < ring->
npoints - 1; i++)
1630 {
1631 double vt;
1633
1634
1635 if (
1636
1637 ((v1.
z <= p->
z) && (v2.
z > p->
z))
1638
1639 || ((v1.
z > p->
z) && (v2.
z <= p->
z)))
1640 {
1641
1642 vt = (double)(p->
z - v1.
z) / (v2.
z - v1.
z);
1643
1644
1645 if (p->
x < v1.
x + vt * (v2.
x - v1.
x))
1646 {
1647
1648 ++cn;
1649 }
1650 }
1651 v1 = v2;
1652 }
1653 }
1654 else
1655 {
1656 for (i = 0; i < ring->
npoints - 1; i++)
1657 {
1658 double vt;
1660
1661
1662 if (
1663
1664 ((v1.
z <= p->
z) && (v2.
z > p->
z))
1665
1666 || ((v1.
z > p->
z) && (v2.
z <= p->
z)))
1667 {
1668
1669 vt = (double)(p->
z - v1.
z) / (v2.
z - v1.
z);
1670
1671
1672 if (p->
y < v1.
y + vt * (v2.
y - v1.
y))
1673 {
1674
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);
1684}
int getPoint3dz_p(const POINTARRAY *pa, uint32_t n, POINT3DZ *point)
#define LWDEBUGF(level, msg,...)
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
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().