PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ lwgeom_solid_contains_lwgeom()

static int lwgeom_solid_contains_lwgeom ( const LWGEOM solid,
const LWGEOM g 
)
inlinestatic

Definition at line 382 of file measures3d.c.

383{
384 const GBOX *b1;
385 const GBOX *b2;
386
387 /* If solid isn't solid it can't contain anything */
388 if (!FLAGS_GET_SOLID(solid->flags))
389 return LW_FALSE;
390
391 b1 = lwgeom_get_bbox(solid);
392 b2 = lwgeom_get_bbox(g);
393
394 /* If box won't contain box, shape won't contain shape */
395 if (!gbox_contains_3d(b1, b2))
396 return LW_FALSE;
397 else /* Raycast upwards in Z */
398 {
399 POINT4D pt;
400 /* We'll skew copies if we're not lucky */
401 LWGEOM *solid_copy = lwgeom_clone_deep(solid);
402 LWGEOM *g_copy = lwgeom_clone_deep(g);
403
404 while (LW_TRUE)
405 {
406 uint8_t is_boundary = LW_FALSE;
407 uint8_t is_inside = LW_FALSE;
408
409 /* take first point */
410 if (!lwgeom_startpoint(g_copy, &pt))
411 return LW_FALSE;
412
413 /* get part of solid that is upwards */
414 LWCOLLECTION *c = lwgeom_clip_to_ordinate_range(solid_copy, 'Z', pt.z, DBL_MAX, 0);
415
416 for (uint32_t i = 0; i < c->ngeoms; i++)
417 {
418 if (c->geoms[i]->type == POLYGONTYPE)
419 {
420 /* 3D raycast along Z is 2D point in polygon */
421 int t = lwpoly_contains_point((LWPOLY *)c->geoms[i], (POINT2D *)&pt);
422
423 if (t == LW_INSIDE)
424 is_inside = !is_inside;
425 else if (t == LW_BOUNDARY)
426 {
427 is_boundary = LW_TRUE;
428 break;
429 }
430 }
431 else if (c->geoms[i]->type == TRIANGLETYPE)
432 {
433 /* 3D raycast along Z is 2D point in polygon */
434 LWTRIANGLE *tri = (LWTRIANGLE *)c->geoms[i];
435 int t = ptarray_contains_point(tri->points, (POINT2D *)&pt);
436
437 if (t == LW_INSIDE)
438 is_inside = !is_inside;
439 else if (t == LW_BOUNDARY)
440 {
441 is_boundary = LW_TRUE;
442 break;
443 }
444 }
445 }
446
448 lwgeom_free(solid_copy);
449 lwgeom_free(g_copy);
450
451 if (is_boundary)
452 {
453 /* randomly skew a bit and restart*/
454 double cx = lwrandom_uniform() - 0.5;
455 double cy = lwrandom_uniform() - 0.5;
456 AFFINE aff = {1, 0, cx, 0, 1, cy, 0, 0, 1, 0, 0, 0};
457
458 solid_copy = lwgeom_clone_deep(solid);
459 lwgeom_affine(solid_copy, &aff);
460
461 g_copy = lwgeom_clone_deep(g);
462 lwgeom_affine(g_copy, &aff);
463
464 continue;
465 }
466 return is_inside;
467 }
468 }
469}
#define LW_FALSE
Definition liblwgeom.h:94
int lwgeom_startpoint(const LWGEOM *lwgeom, POINT4D *pt)
Definition lwgeom.c:2249
void lwgeom_free(LWGEOM *geom)
Definition lwgeom.c:1246
LWCOLLECTION * lwgeom_clip_to_ordinate_range(const LWGEOM *lwin, char ordinate, double from, double to, double offset)
Given a geometry clip based on the from/to range of one of its ordinates (x, y, z,...
#define POLYGONTYPE
Definition liblwgeom.h:104
void lwgeom_affine(LWGEOM *geom, const AFFINE *affine)
Definition lwgeom.c:2111
void lwcollection_free(LWCOLLECTION *col)
#define FLAGS_GET_SOLID(flags)
Definition liblwgeom.h:170
#define TRIANGLETYPE
Definition liblwgeom.h:115
#define LW_TRUE
Return types for functions with status returns.
Definition liblwgeom.h:93
const GBOX * lwgeom_get_bbox(const LWGEOM *lwgeom)
Get a non-empty geometry bounding box, computing and caching it if not already there.
Definition lwgeom.c:771
LWGEOM * lwgeom_clone_deep(const LWGEOM *lwgeom)
Deep clone an LWGEOM, everything is copied.
Definition lwgeom.c:557
#define LW_INSIDE
Constants for point-in-polygon return values.
#define LW_BOUNDARY
int ptarray_contains_point(const POINTARRAY *pa, const POINT2D *pt)
The following is based on the "Fast Winding Number Inclusion of a Point in a Polygon" algorithm by Da...
Definition ptarray.c:755
int lwpoly_contains_point(const LWPOLY *poly, const POINT2D *pt)
Definition lwpoly.c:531
double lwrandom_uniform(void)
Definition lwrandom.c:94
static int gbox_contains_3d(const GBOX *g1, const GBOX *g2)
Definition measures3d.c:375
uint32_t ngeoms
Definition liblwgeom.h:580
LWGEOM ** geoms
Definition liblwgeom.h:575
uint8_t type
Definition liblwgeom.h:462
lwflags_t flags
Definition liblwgeom.h:461
double z
Definition liblwgeom.h:414

References LWGEOM::flags, FLAGS_GET_SOLID, gbox_contains_3d(), LWCOLLECTION::geoms, LW_BOUNDARY, LW_FALSE, LW_INSIDE, LW_TRUE, lwcollection_free(), lwgeom_affine(), lwgeom_clip_to_ordinate_range(), lwgeom_clone_deep(), lwgeom_free(), lwgeom_get_bbox(), lwgeom_startpoint(), lwpoly_contains_point(), lwrandom_uniform(), LWCOLLECTION::ngeoms, LWTRIANGLE::points, POLYGONTYPE, ptarray_contains_point(), TRIANGLETYPE, LWGEOM::type, and POINT4D::z.

Referenced by lwgeom_mindistance3d_tolerance().

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