PostGIS 3.0.6dev-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 1567 of file measures3d.c.

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