Polygon A contains Polygon B.
(rings_a: &[Vec<[f64; 2]>], rings_b: &[Vec<[f64; 2]>])
| 191 | |
| 192 | /// Polygon A contains Polygon B. |
| 193 | fn 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). |
| 235 | fn edges_properly_cross(a1: [f64; 2], a2: [f64; 2], b1: [f64; 2], b2: [f64; 2]) -> bool { |
no test coverage detected