diff options
| author | Arne Dußin | 2020-12-15 00:46:54 +0100 |
|---|---|---|
| committer | Arne Dußin | 2020-12-15 22:51:46 +0100 |
| commit | 9799d3c6a8f0c242668203a1c70d7b6cfed3e855 (patch) | |
| tree | 9116acbc886f680f82309a42b4e6147e65c1433b /src/math | |
| parent | 3bc690803fb59493ea8180fd630d65b3e26642d0 (diff) | |
| download | graf_karto-9799d3c6a8f0c242668203a1c70d7b6cfed3e855.tar.gz graf_karto-9799d3c6a8f0c242668203a1c70d7b6cfed3e855.zip | |
Refactor to make interaction between tools easier
Diffstat (limited to 'src/math')
| -rw-r--r-- | src/math/line_segment.rs | 3 | ||||
| -rw-r--r-- | src/math/mod.rs | 18 | ||||
| -rw-r--r-- | src/math/polygon/mod.rs | 4 | ||||
| -rw-r--r-- | src/math/rect.rs | 36 | ||||
| -rw-r--r-- | src/math/surface.rs | 21 |
5 files changed, 65 insertions, 17 deletions
diff --git a/src/math/line_segment.rs b/src/math/line_segment.rs index 94f58b2..b496787 100644 --- a/src/math/line_segment.rs +++ b/src/math/line_segment.rs @@ -2,9 +2,10 @@ use super::{Rect, Surface, TripletOrientation, Vec2}; use alga::general::{ClosedDiv, ClosedMul, ClosedSub}; use nalgebra::{RealField, Scalar}; use num_traits::Zero; +use serde::{Deserialize, Serialize}; use std::cmp::Ordering; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Deserialize, Serialize)] pub struct LineSegment<T: Scalar + Copy> { pub start: Vec2<T>, pub end: Vec2<T>, diff --git a/src/math/mod.rs b/src/math/mod.rs index 279affc..829a3c5 100644 --- a/src/math/mod.rs +++ b/src/math/mod.rs @@ -1,34 +1,20 @@ pub mod line_segment; pub mod polygon; pub mod rect; +pub mod surface; pub mod triangle; pub mod vec2; pub use self::line_segment::*; pub use self::polygon::*; pub use self::rect::*; +pub use self::surface::*; pub use self::triangle::*; pub use self::vec2::*; -use nalgebra::Scalar; use num_traits::Float; use std::cmp::Ordering; -/// Trait that describes an area in the vector space on the field of T -pub trait Surface<T: Scalar + Copy> { - /// Checks if a point lies on this surface. - fn contains_point(&self, point: &Vec2<T>) -> bool; - - /// Checks if a line segment is entirely contained by this surface. - fn contains_line_segment(&self, line_segment: &LineSegment<T>) -> bool; - - /// Checks if a rectangle is entirely contained inside this surface. - fn contains_rect(&self, rect: &Rect<T>) -> bool; - - /// Checks if a polygon is contained wholly by this surface. - fn contains_polygon(&self, polygon: &Polygon<T>) -> bool; -} - /// Round a floating point number to the nearest step given by the step argument. For instance, if /// the step is 0.5, then all numbers from 0.0 to 0.24999... will be 0., while all numbers from /// 0.25 to 0.74999... will be 0.5 and so on. diff --git a/src/math/polygon/mod.rs b/src/math/polygon/mod.rs index c9dad91..98b1570 100644 --- a/src/math/polygon/mod.rs +++ b/src/math/polygon/mod.rs @@ -409,6 +409,10 @@ impl< true } + + fn is_inside_rect(&self, rect: &Rect<T>) -> bool { + rect.contains_polygon(&self) + } } /* Helper function to calculate the combined angle of a set of points when connecting them one diff --git a/src/math/rect.rs b/src/math/rect.rs index 5603642..befa4da 100644 --- a/src/math/rect.rs +++ b/src/math/rect.rs @@ -84,6 +84,38 @@ impl<T: Scalar + Copy> Rect<T> { } } + /// Function to calculate the bounding rectangle of n vertices provided. The order of them is + /// not relevant and a point that is contained by the vertices will not change the result. + /// + /// # Panics + /// If there is not at least one vertex in the vertices slice, the function will panic, since it + /// is impossible to calculate any bounds in such a case. + pub fn bounding_rect_n(vertices: &[Vec2<T>]) -> Self + where + T: RealField, + { + if vertices.is_empty() { + panic!("Cannot create bounding rectangle without any vertices"); + } + + let mut min = vertices[0]; + let mut max = vertices[1]; + + for vertex in vertices.iter().skip(1) { + min.x = super::partial_min(min.x, vertex.x); + min.y = super::partial_min(min.y, vertex.y); + max.x = super::partial_max(max.x, vertex.x); + max.y = super::partial_max(max.y, vertex.y); + } + + Self { + x: min.x, + y: min.y, + w: max.x - min.x, + h: max.y - min.y + } + } + /// Get the shortest way that must be applied to this Rect to clear out of /// another Rect of the same type so that they would not intersect any more. pub fn shortest_way_out(&self, of: &Rect<T>) -> Vec2<T> @@ -145,6 +177,10 @@ impl<T: Scalar + Copy + PartialOrd + ClosedAdd + ClosedSub + Zero> Surface<T> fo .iter() .all(|&corner| self.contains_point(&corner)) } + + fn is_inside_rect(&self, rect: &Rect<T>) -> bool { + rect.contains_rect(&self) + } } // This is sad, but also sadly necessary :/ diff --git a/src/math/surface.rs b/src/math/surface.rs new file mode 100644 index 0000000..da265d8 --- /dev/null +++ b/src/math/surface.rs @@ -0,0 +1,21 @@ +use super::{LineSegment, Polygon, Rect, Vec2}; +use nalgebra::Scalar; + +/// Trait that describes an area in the vector space on the field of T +pub trait Surface<T: Scalar + Copy> { + /// Checks if a point lies on this surface. + fn contains_point(&self, point: &Vec2<T>) -> bool; + + /// Checks if a line segment is entirely contained by this surface. + fn contains_line_segment(&self, line_segment: &LineSegment<T>) -> bool; + + /// Checks if a rectangle is entirely contained inside this surface. + fn contains_rect(&self, rect: &Rect<T>) -> bool; + + /// Checks if a polygon is contained wholly by this surface. + fn contains_polygon(&self, polygon: &Polygon<T>) -> bool; + + /// Checks if this surface is contained by the rect in it's entirety. Think of it as the reverse + /// operation for contains_... on a rectangle. + fn is_inside_rect(&self, rect: &Rect<T>) -> bool; +} |
