aboutsummaryrefslogtreecommitdiff
path: root/src/math/triangle.rs
diff options
context:
space:
mode:
authorArne Dußin2020-11-23 22:40:12 +0100
committerArne Dußin2020-11-23 22:46:06 +0100
commita6c141908ddb94a0ebb3a1ac95d3f8444e13e3b5 (patch)
treeef7653acaf21314bad94dce86689980b373df92b /src/math/triangle.rs
parent1363c7713d19bd733a97dff5727827cf7684a27b (diff)
downloadgraf_karto-a6c141908ddb94a0ebb3a1ac95d3f8444e13e3b5.tar.gz
graf_karto-a6c141908ddb94a0ebb3a1ac95d3f8444e13e3b5.zip
Fix corner case not being handled
Previously, the algorithm to check, if a line-segment is inside a polygon did not have a special case for when the start or end of the segment is on a polygon corner. In case this corner is reflexive, checking against one line between this corner and an adjacent one may not be enough.
Diffstat (limited to 'src/math/triangle.rs')
-rw-r--r--src/math/triangle.rs35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/math/triangle.rs b/src/math/triangle.rs
index 5cf16e5..35bdcec 100644
--- a/src/math/triangle.rs
+++ b/src/math/triangle.rs
@@ -4,6 +4,7 @@ use nalgebra::{RealField, Scalar};
use num_traits::Zero;
/// Represents a triangle
+#[derive(Debug)]
pub struct Triangle<T: Scalar + Copy> {
/// The three corners of the triangle. Internally, it is made sure that the corners are always
/// ordered in a counterclockwise manner, to make operations like contains simpler.
@@ -80,6 +81,25 @@ impl<T: Scalar + Copy> Into<[Vec2<T>; 3]> for Triangle<T> {
}
}
+impl<T: Scalar + Copy + PartialEq> PartialEq for Triangle<T> {
+ fn eq(&self, other: &Self) -> bool {
+ // The indexes of the elements are not important, so try all shifting options.
+ for shift in 0..=2 {
+ if self
+ .corners
+ .iter()
+ .enumerate()
+ .find(|(i, &c)| c != other.corners[(i + shift) % 3])
+ .is_none()
+ {
+ return true;
+ }
+ }
+
+ false
+ }
+}
+
#[derive(PartialEq, Eq)]
pub(crate) enum TripletOrientation {
Clockwise,
@@ -187,6 +207,21 @@ mod test {
}
#[test]
+ fn equality() {
+ let a = Vec2::new(0., 0.);
+ let b = Vec2::new(-1., -1.);
+ let c = Vec2::new(-2., 0.);
+ let d = Vec2::new(-3., 0.);
+
+ let cmp = Triangle::new(a, b, c);
+
+ assert_eq!(Triangle::new(a, b, c), cmp);
+ assert_eq!(Triangle::new(c, b, a), cmp);
+ assert_eq!(Triangle::new(b, a, c), cmp);
+ assert!(Triangle::new(a, b, d) != cmp);
+ }
+
+ #[test]
fn triplet_angle() {
assert_eq!(
super::triplet_angle(Vec2::new(0., 0.), Vec2::new(0., -1.), Vec2::new(-1., -1.)),