From cf3c8378557457363853d6795e4ddf9e70a4738e Mon Sep 17 00:00:00 2001 From: Arne Dußin Date: Thu, 26 Nov 2020 20:50:30 +0100 Subject: Make polygons deletable Before, the deletion tool was not targeting polygons. I also took the liberty to broaden the functionality of the surface trait, which now can check if a rectangle or polygon is contained. --- src/math/polygon/mod.rs | 50 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) (limited to 'src/math/polygon') diff --git a/src/math/polygon/mod.rs b/src/math/polygon/mod.rs index ed48751..c9dad91 100644 --- a/src/math/polygon/mod.rs +++ b/src/math/polygon/mod.rs @@ -6,7 +6,7 @@ pub mod triangulate; pub use polygon_graph::*; pub use triangulate::*; -use super::{LineSegment, Surface, TripletOrientation, Vec2}; +use super::{LineSegment, Rect, Surface, TripletOrientation, Vec2}; use crate::math; use nalgebra::{ClosedDiv, ClosedMul, ClosedSub, RealField, Scalar}; use num_traits::Zero; @@ -361,6 +361,54 @@ impl< true } + + fn contains_rect(&self, rect: &Rect) -> bool { + /* Turn the rectangle into a vector with its hull line segments. If all hull segments are + * contained in the polygon, the rectangle is contained completely. + */ + let hull_edges = [ + // Top left to bottom left. + LineSegment::new( + Vec2::new(rect.x, rect.y), + Vec2::new(rect.x, rect.y + rect.h), + ), + // Bottom left to bottom right. + LineSegment::new( + Vec2::new(rect.x, rect.y + rect.h), + Vec2::new(rect.x + rect.w, rect.y + rect.h), + ), + // Bottom right to top right. + LineSegment::new( + Vec2::new(rect.x + rect.w, rect.y + rect.h), + Vec2::new(rect.x + rect.w, rect.y), + ), + // Top right to top left. + LineSegment::new( + Vec2::new(rect.x + rect.w, rect.y), + Vec2::new(rect.x, rect.y), + ), + ]; + + hull_edges + .iter() + .all(|edge| self.contains_line_segment(edge)) + } + + fn contains_polygon(&self, polygon: &Polygon) -> bool { + /* Check for all edges of the polygon that they are contained by the polygon. If they all + * are, then the polygon itself must also be contained. + */ + for i in 0..polygon.corners.len() { + let next = (i + 1) % polygon.corners.len(); + if !self + .contains_line_segment(&LineSegment::new(polygon.corners[i], polygon.corners[next])) + { + return false; + } + } + + true + } } /* Helper function to calculate the combined angle of a set of points when connecting them one -- cgit v1.2.3-70-g09d2