PostGIS  2.5.7dev-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 1277 of file measures3d.c.

1278 {
1279 
1280  uint32_t cn = 0; /* the crossing number counter */
1281  uint32_t i;
1282  POINT3DZ v1, v2;
1283 
1284  POINT3DZ first, last;
1285 
1286  getPoint3dz_p(ring, 0, &first);
1287  getPoint3dz_p(ring, ring->npoints-1, &last);
1288  if ( memcmp(&first, &last, sizeof(POINT3DZ)) )
1289  {
1290  lwerror("pt_in_ring_3d: V[n] != V[0] (%g %g %g!= %g %g %g)",
1291  first.x, first.y, first.z, last.x, last.y, last.z);
1292  return LW_FALSE;
1293  }
1294 
1295  LWDEBUGF(2, "pt_in_ring_3d called with point: %g %g %g", p->x, p->y, p->z);
1296  /* printPA(ring); */
1297 
1298  /* loop through all edges of the polygon */
1299  getPoint3dz_p(ring, 0, &v1);
1300 
1301 
1302  if(fabs(plane->pv.z)>=fabs(plane->pv.x)&&fabs(plane->pv.z)>=fabs(plane->pv.y)) /*If the z vector of the normal vector to the plane is larger than x and y vector we project the ring to the xy-plane*/
1303  {
1304  for (i=0; i<ring->npoints-1; i++)
1305  {
1306  double vt;
1307  getPoint3dz_p(ring, i+1, &v2);
1308 
1309  /* edge from vertex i to vertex i+1 */
1310  if
1311  (
1312  /* an upward crossing */
1313  ((v1.y <= p->y) && (v2.y > p->y))
1314  /* a downward crossing */
1315  || ((v1.y > p->y) && (v2.y <= p->y))
1316  )
1317  {
1318 
1319  vt = (double)(p->y - v1.y) / (v2.y - v1.y);
1320 
1321  /* P.x <intersect */
1322  if (p->x < v1.x + vt * (v2.x - v1.x))
1323  {
1324  /* a valid crossing of y=p.y right of p.x */
1325  ++cn;
1326  }
1327  }
1328  v1 = v2;
1329  }
1330  }
1331  else if(fabs(plane->pv.y)>=fabs(plane->pv.x)&&fabs(plane->pv.y)>=fabs(plane->pv.z)) /*If the y vector of the normal vector to the plane is larger than x and z vector we project the ring to the xz-plane*/
1332  {
1333  for (i=0; i<ring->npoints-1; i++)
1334  {
1335  double vt;
1336  getPoint3dz_p(ring, i+1, &v2);
1337 
1338  /* edge from vertex i to vertex i+1 */
1339  if
1340  (
1341  /* an upward crossing */
1342  ((v1.z <= p->z) && (v2.z > p->z))
1343  /* a downward crossing */
1344  || ((v1.z > p->z) && (v2.z <= p->z))
1345  )
1346  {
1347 
1348  vt = (double)(p->z - v1.z) / (v2.z - v1.z);
1349 
1350  /* P.x <intersect */
1351  if (p->x < v1.x + vt * (v2.x - v1.x))
1352  {
1353  /* a valid crossing of y=p.y right of p.x */
1354  ++cn;
1355  }
1356  }
1357  v1 = v2;
1358  }
1359  }
1360  else /*Hopefully we only have the cases where x part of the normal vector is largest left*/
1361  {
1362  for (i=0; i<ring->npoints-1; i++)
1363  {
1364  double vt;
1365  getPoint3dz_p(ring, i+1, &v2);
1366 
1367  /* edge from vertex i to vertex i+1 */
1368  if
1369  (
1370  /* an upward crossing */
1371  ((v1.z <= p->z) && (v2.z > p->z))
1372  /* a downward crossing */
1373  || ((v1.z > p->z) && (v2.z <= p->z))
1374  )
1375  {
1376 
1377  vt = (double)(p->z - v1.z) / (v2.z - v1.z);
1378 
1379  /* P.x <intersect */
1380  if (p->y < v1.y + vt * (v2.y - v1.y))
1381  {
1382  /* a valid crossing of y=p.y right of p.x */
1383  ++cn;
1384  }
1385  }
1386  v1 = v2;
1387  }
1388  }
1389  LWDEBUGF(3, "pt_in_ring_3d returning %d", cn&1);
1390 
1391  return (cn&1); /* 0 if even (out), and 1 if odd (in) */
1392 }
#define LW_FALSE
Definition: liblwgeom.h:77
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:337
double x
Definition: liblwgeom.h:337
double y
Definition: liblwgeom.h:337
uint32_t npoints
Definition: liblwgeom.h:374
double z
Definition: measures3d.h:51
double x
Definition: measures3d.h:51
double y
Definition: measures3d.h:51
unsigned int uint32_t
Definition: uthash.h:78

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(), and lw_dist3d_ptarray_poly().

Here is the call graph for this function:
Here is the caller graph for this function: