PostGIS  2.2.8dev-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 1217 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().

1218 {
1219 
1220  int cn = 0; /* the crossing number counter */
1221  int i;
1222  POINT3DZ v1, v2;
1223 
1224  POINT3DZ first, last;
1225 
1226  getPoint3dz_p(ring, 0, &first);
1227  getPoint3dz_p(ring, ring->npoints-1, &last);
1228  if ( memcmp(&first, &last, sizeof(POINT3DZ)) )
1229  {
1230  lwerror("pt_in_ring_3d: V[n] != V[0] (%g %g %g!= %g %g %g)",
1231  first.x, first.y, first.z, last.x, last.y, last.z);
1232  return LW_FALSE;
1233  }
1234 
1235  LWDEBUGF(2, "pt_in_ring_3d called with point: %g %g %g", p->x, p->y, p->z);
1236  /* printPA(ring); */
1237 
1238  /* loop through all edges of the polygon */
1239  getPoint3dz_p(ring, 0, &v1);
1240 
1241 
1242  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*/
1243  {
1244  for (i=0; i<ring->npoints-1; i++)
1245  {
1246  double vt;
1247  getPoint3dz_p(ring, i+1, &v2);
1248 
1249  /* edge from vertex i to vertex i+1 */
1250  if
1251  (
1252  /* an upward crossing */
1253  ((v1.y <= p->y) && (v2.y > p->y))
1254  /* a downward crossing */
1255  || ((v1.y > p->y) && (v2.y <= p->y))
1256  )
1257  {
1258 
1259  vt = (double)(p->y - v1.y) / (v2.y - v1.y);
1260 
1261  /* P.x <intersect */
1262  if (p->x < v1.x + vt * (v2.x - v1.x))
1263  {
1264  /* a valid crossing of y=p.y right of p.x */
1265  ++cn;
1266  }
1267  }
1268  v1 = v2;
1269  }
1270  }
1271  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*/
1272  {
1273  for (i=0; i<ring->npoints-1; i++)
1274  {
1275  double vt;
1276  getPoint3dz_p(ring, i+1, &v2);
1277 
1278  /* edge from vertex i to vertex i+1 */
1279  if
1280  (
1281  /* an upward crossing */
1282  ((v1.z <= p->z) && (v2.z > p->z))
1283  /* a downward crossing */
1284  || ((v1.z > p->z) && (v2.z <= p->z))
1285  )
1286  {
1287 
1288  vt = (double)(p->z - v1.z) / (v2.z - v1.z);
1289 
1290  /* P.x <intersect */
1291  if (p->x < v1.x + vt * (v2.x - v1.x))
1292  {
1293  /* a valid crossing of y=p.y right of p.x */
1294  ++cn;
1295  }
1296  }
1297  v1 = v2;
1298  }
1299  }
1300  else /*Hopefully we only have the cases where x part of the normal vector is largest left*/
1301  {
1302  for (i=0; i<ring->npoints-1; i++)
1303  {
1304  double vt;
1305  getPoint3dz_p(ring, i+1, &v2);
1306 
1307  /* edge from vertex i to vertex i+1 */
1308  if
1309  (
1310  /* an upward crossing */
1311  ((v1.z <= p->z) && (v2.z > p->z))
1312  /* a downward crossing */
1313  || ((v1.z > p->z) && (v2.z <= p->z))
1314  )
1315  {
1316 
1317  vt = (double)(p->z - v1.z) / (v2.z - v1.z);
1318 
1319  /* P.x <intersect */
1320  if (p->y < v1.y + vt * (v2.y - v1.y))
1321  {
1322  /* a valid crossing of y=p.y right of p.x */
1323  ++cn;
1324  }
1325  }
1326  v1 = v2;
1327  }
1328  }
1329  LWDEBUGF(3, "pt_in_ring_3d returning %d", cn&1);
1330 
1331  return (cn&1); /* 0 if even (out), and 1 if odd (in) */
1332 }
double z
Definition: liblwgeom.h:318
double y
Definition: liblwgeom.h:318
double x
Definition: liblwgeom.h:318
double z
Definition: measures3d.h:37
int npoints
Definition: liblwgeom.h:355
VECTOR3D pv
Definition: measures3d.h:44
double y
Definition: measures3d.h:37
int getPoint3dz_p(const POINTARRAY *pa, int n, POINT3DZ *point)
Definition: lwgeom_api.c:319
#define LW_FALSE
Definition: liblwgeom.h:62
double x
Definition: measures3d.h:37
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:55
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:74
Here is the call graph for this function:
Here is the caller graph for this function: