MCPcopy Create free account
hub / github.com/NodeDB-Lab/nodedb / polygon_contains_polygon

Function polygon_contains_polygon

nodedb-spatial/src/predicates/contains.rs:193–232  ·  view source on GitHub ↗

Polygon A contains Polygon B.

(rings_a: &[Vec<[f64; 2]>], rings_b: &[Vec<[f64; 2]>])

Source from the content-addressed store, hash-verified

191
192/// Polygon A contains Polygon B.
193fn polygon_contains_polygon(rings_a: &[Vec<[f64; 2]>], rings_b: &[Vec<[f64; 2]>]) -> bool {
194 let Some(ext_b) = rings_b.first() else {
195 return true;
196 };
197
198 // All vertices of B's exterior must be inside A (or on A's boundary,
199 // but at least one must be strictly inside).
200 let Some(ext_a) = rings_a.first() else {
201 return false;
202 };
203
204 for pt in ext_b {
205 if !point_in_polygon(pt[0], pt[1], ext_a) && !point_on_ring_boundary(*pt, ext_a) {
206 return false;
207 }
208 }
209
210 // B's exterior must not be inside any hole of A.
211 for hole in &rings_a[1..] {
212 for pt in ext_b {
213 if point_in_polygon(pt[0], pt[1], hole) {
214 return false;
215 }
216 }
217 }
218
219 // No proper edge crossings between A's exterior and B's exterior.
220 let a_edges = ring_edges(ext_a);
221 let b_edges = ring_edges(ext_b);
222 for &(a1, a2) in &a_edges {
223 for &(b1, b2) in &b_edges {
224 if edges_properly_cross(a1, a2, b1, b2) {
225 return false;
226 }
227 }
228 }
229
230 // At least one vertex of B must be strictly inside A.
231 ext_b.iter().any(|pt| polygon_contains_point(rings_a, *pt))
232}
233
234/// Whether two segments properly cross (not just touch at endpoints).
235fn edges_properly_cross(a1: [f64; 2], a2: [f64; 2], b1: [f64; 2], b2: [f64; 2]) -> bool {

Callers 1

st_containsFunction · 0.85

Calls 7

point_in_polygonFunction · 0.85
point_on_ring_boundaryFunction · 0.85
ring_edgesFunction · 0.85
edges_properly_crossFunction · 0.85
polygon_contains_pointFunction · 0.85
firstMethod · 0.80
iterMethod · 0.45

Tested by

no test coverage detected