Opened 6 years ago
Closed 6 years ago
#4278 closed defect (fixed)
ST_3DIntersects / ST_3DDistance solid aware in LWGEOM
Reported by: | komzpa | Owned by: | komzpa |
---|---|---|---|
Priority: | medium | Milestone: | PostGIS 3.0.0 |
Component: | postgis | Version: | 2.4.x |
Keywords: | Cc: |
Description
From https://github.com/postgis/postgis/pull/351#issuecomment-449620811
To implement solid-aware ST_Distance and ST_Intersects we seem to need to add a not super large bit of logic:
distance = mindist_as_it_is(geom1, geom2); if (box1 &&& box2 and distance > 0) { /* check if we are completely inside */ geom1, box1, geom2, box2 = swap_so_that_box1_is_inside_box2(); if (not ST_IsSold(geom2)) return distance; pt1 = take_any_point_in(geom1); if (raycast_count_hits_to_infinity_from_point(pt1, geom2) is odd) return 0 else return distance; }
This way we can avoid the semantic change altogether.
Change History (6)
comment:1 by , 6 years ago
comment:2 by , 6 years ago
@komzpa could you detail ? I do not understand how lwgeom_clip_to_ordinate_range helps here ...
A ray casting in 3D means to me testing intersection between a ray and each face of the mesh.
comment:3 by , 6 years ago
Ray from point to infinity can be expressed as a box (Xmin=X[-eps], Xmax=X[+eps], Ymin=Y[-eps], Ymax=Y[+eps], Zmin=Z, Zmax = infinity). You can intersect such box with any dimension geometry by feeding the ranges into lwgeom_clip_to_ordinate_range.
Afterwards you get a bunch of super tiny polygons with 2D area=0, area = eps2. Count ones with area>0, that will get you a good approximation of number of hits. If you find a hit with area of 0 < area < eps2, it's on the edge, mark it with a TODO:FIXME and emit a warning.
comment:4 by , 6 years ago
Owner: | changed from | to
---|
A dead simple way to perform raycast is to make three calls to lwgeom_clip_to_ordinate_range and count number of geometries in result. Need to teach it not to drop ones that lost their dimensionality.