diff options
| author | Arne Dußin | 2020-11-23 23:25:45 +0100 |
|---|---|---|
| committer | Arne Dußin | 2020-11-23 23:25:45 +0100 |
| commit | 3b0c99351da92410bbfaba233e40376b767cb64e (patch) | |
| tree | 56bd28470942bc79120407a9f646b07aff5b570a /src/math | |
| parent | a6c141908ddb94a0ebb3a1ac95d3f8444e13e3b5 (diff) | |
| download | graf_karto-3b0c99351da92410bbfaba233e40376b767cb64e.tar.gz graf_karto-3b0c99351da92410bbfaba233e40376b767cb64e.zip | |
Add triangulation function
Diffstat (limited to 'src/math')
| -rw-r--r-- | src/math/polygon/mod.rs | 31 | ||||
| -rw-r--r-- | src/math/polygon/triangulate.rs | 30 |
2 files changed, 49 insertions, 12 deletions
diff --git a/src/math/polygon/mod.rs b/src/math/polygon/mod.rs index e19e097..cc89169 100644 --- a/src/math/polygon/mod.rs +++ b/src/math/polygon/mod.rs @@ -42,7 +42,15 @@ impl<T: Scalar + Copy> Polygon<T> { } impl< - T: Scalar + Copy + ClosedSub + ClosedMul + ClosedDiv + Neg<Output = T> + PartialOrd + Zero, + T: Scalar + + Copy + + ClosedSub + + ClosedMul + + ClosedDiv + + Neg<Output = T> + + PartialOrd + + RealField + + Zero, > Surface<T> for Polygon<T> { fn contains_point(&self, p: &Vec2<T>) -> bool { @@ -145,18 +153,11 @@ impl< let prev = (c + self.corners.len() - 1) % self.corners.len(); let next = (c + 1) % self.corners.len(); - let last_edge_orientation = - math::triplet_orientation(self.corners[prev], self.corners[c], p); - let current_edge_orientation = - math::triplet_orientation(self.corners[c], self.corners[next], p); + let edge_angle = + math::triplet_angle(self.corners[prev], self.corners[c], self.corners[next]); + let vec_angle = math::triplet_angle(self.corners[prev], self.corners[c], p); - if last_edge_orientation == TripletOrientation::Clockwise - && current_edge_orientation == TripletOrientation::Clockwise - { - false - } else { - true - } + vec_angle == T::zero() || vec_angle >= edge_angle }; for c in 0..self.corners.len() { @@ -297,6 +298,12 @@ mod test { assert!( polygon.contains_line_segment(&LineSegment::new(Vec2::new(2., 0.5), Vec2::new(4., 0.))) ); + + // Start and end point on vertex, not pointing in the dir of adjacent edge normals, + // not completely inside. + assert!( + !polygon.contains_line_segment(&LineSegment::new(Vec2::new(4., 2.), Vec2::new(0., 0.))) + ); } #[test] diff --git a/src/math/polygon/triangulate.rs b/src/math/polygon/triangulate.rs index 096a1c6..78dfa03 100644 --- a/src/math/polygon/triangulate.rs +++ b/src/math/polygon/triangulate.rs @@ -117,3 +117,33 @@ where triangles } + +#[cfg(test)] +mod test { + use super::*; + use crate::math::Vec2; + + #[test] + fn triangulate() { + let polygon = Polygon::new(vec![ + Vec2::new(0., 0.), + Vec2::new(0., 4.5), + Vec2::new(6.5, 4.5), + Vec2::new(5.5, 0.), + Vec2::new(5.5, 3.), + Vec2::new(1.5, 3.), + Vec2::new(1.5, 1.), + Vec2::new(2., 0.5), + Vec2::new(4., 2.), + Vec2::new(4., 0.), + ]); + + let triangles = super::triangulate(polygon); + + assert_eq!(triangles.len(), 8); + assert_eq!( + triangles[0], + (Triangle::new(Vec2::new(2., 0.5), Vec2::new(4., 2.), Vec2::new(4., 0.))) + ); + } +} |
