PostGIS  2.5.1dev-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 1238 of file measures3d.c.

References getPoint3dz_p(), LW_FALSE, LWDEBUGF, lwerror(), POINTARRAY::npoints, PLANE3D::pv, VECTOR3D::x, POINT3DZ::x, VECTOR3D::y, POINT3DZ::y, VECTOR3D::z, and POINT3DZ::z.

Referenced by lw_dist3d_pt_poly(), and lw_dist3d_ptarray_poly().

1239 {
1240 
1241  uint32_t cn = 0; /* the crossing number counter */
1242  uint32_t i;
1243  POINT3DZ v1, v2;
1244 
1245  POINT3DZ first, last;
1246 
1247  getPoint3dz_p(ring, 0, &first);
1248  getPoint3dz_p(ring, ring->npoints-1, &last);
1249  if ( memcmp(&first, &last, sizeof(POINT3DZ)) )
1250  {
1251  lwerror("pt_in_ring_3d: V[n] != V[0] (%g %g %g!= %g %g %g)",
1252  first.x, first.y, first.z, last.x, last.y, last.z);
1253  return LW_FALSE;
1254  }
1255 
1256  LWDEBUGF(2, "pt_in_ring_3d called with point: %g %g %g", p->x, p->y, p->z);
1257  /* printPA(ring); */
1258 
1259  /* loop through all edges of the polygon */
1260  getPoint3dz_p(ring, 0, &v1);
1261 
1262 
1263  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*/
1264  {
1265  for (i=0; i<ring->npoints-1; i++)
1266  {
1267  double vt;
1268  getPoint3dz_p(ring, i+1, &v2);
1269 
1270  /* edge from vertex i to vertex i+1 */
1271  if
1272  (
1273  /* an upward crossing */
1274  ((v1.y <= p->y) && (v2.y > p->y))
1275  /* a downward crossing */
1276  || ((v1.y > p->y) && (v2.y <= p->y))
1277  )
1278  {
1279 
1280  vt = (double)(p->y - v1.y) / (v2.y - v1.y);
1281 
1282  /* P.x <intersect */
1283  if (p->x < v1.x + vt * (v2.x - v1.x))
1284  {
1285  /* a valid crossing of y=p.y right of p.x */
1286  ++cn;
1287  }
1288  }
1289  v1 = v2;
1290  }
1291  }
1292  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*/
1293  {
1294  for (i=0; i<ring->npoints-1; i++)
1295  {
1296  double vt;
1297  getPoint3dz_p(ring, i+1, &v2);
1298 
1299  /* edge from vertex i to vertex i+1 */
1300  if
1301  (
1302  /* an upward crossing */
1303  ((v1.z <= p->z) && (v2.z > p->z))
1304  /* a downward crossing */
1305  || ((v1.z > p->z) && (v2.z <= p->z))
1306  )
1307  {
1308 
1309  vt = (double)(p->z - v1.z) / (v2.z - v1.z);
1310 
1311  /* P.x <intersect */
1312  if (p->x < v1.x + vt * (v2.x - v1.x))
1313  {
1314  /* a valid crossing of y=p.y right of p.x */
1315  ++cn;
1316  }
1317  }
1318  v1 = v2;
1319  }
1320  }
1321  else /*Hopefully we only have the cases where x part of the normal vector is largest left*/
1322  {
1323  for (i=0; i<ring->npoints-1; i++)
1324  {
1325  double vt;
1326  getPoint3dz_p(ring, i+1, &v2);
1327 
1328  /* edge from vertex i to vertex i+1 */
1329  if
1330  (
1331  /* an upward crossing */
1332  ((v1.z <= p->z) && (v2.z > p->z))
1333  /* a downward crossing */
1334  || ((v1.z > p->z) && (v2.z <= p->z))
1335  )
1336  {
1337 
1338  vt = (double)(p->z - v1.z) / (v2.z - v1.z);
1339 
1340  /* P.x <intersect */
1341  if (p->y < v1.y + vt * (v2.y - v1.y))
1342  {
1343  /* a valid crossing of y=p.y right of p.x */
1344  ++cn;
1345  }
1346  }
1347  v1 = v2;
1348  }
1349  }
1350  LWDEBUGF(3, "pt_in_ring_3d returning %d", cn&1);
1351 
1352  return (cn&1); /* 0 if even (out), and 1 if odd (in) */
1353 }
double z
Definition: liblwgeom.h:336
double y
Definition: liblwgeom.h:336
double x
Definition: liblwgeom.h:336
double z
Definition: measures3d.h:51
VECTOR3D pv
Definition: measures3d.h:58
double y
Definition: measures3d.h:51
unsigned int uint32_t
Definition: uthash.h:78
#define LW_FALSE
Definition: liblwgeom.h:76
int getPoint3dz_p(const POINTARRAY *pa, uint32_t n, POINT3DZ *point)
Definition: lwgeom_api.c:205
double x
Definition: measures3d.h:51
#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
uint32_t npoints
Definition: liblwgeom.h:373
Here is the call graph for this function:
Here is the caller graph for this function: