Skip to content

Commit

Permalink
Fix 2D Triangle::contains_point too
Browse files Browse the repository at this point in the history
  • Loading branch information
sebcrozet committed Dec 7, 2022
1 parent 5fc865b commit b37cedf
Showing 1 changed file with 78 additions and 16 deletions.
94 changes: 78 additions & 16 deletions src/shape/triangle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -452,8 +452,23 @@ impl Triangle {
}

/// Tests if a point is inside of this triangle.
#[cfg(feature = "dim2")]
pub fn contains_point(&self, p: &Point<Real>) -> bool {
let ab = self.b - self.a;
let bc = self.c - self.b;
let ca = self.a - self.c;
let sgn1 = ab.perp(&(p - self.a));
let sgn2 = bc.perp(&(p - self.b));
let sgn3 = ca.perp(&(p - self.c));
sgn1.signum() * sgn2.signum() >= 0.0
&& sgn1.signum() * sgn3.signum() >= 0.0
&& sgn2.signum() * sgn3.signum() >= 0.0
}

/// Tests if a point is inside of this triangle.
#[cfg(feature = "dim3")]
pub fn contains_point(&self, p: &Point<Real>) -> bool {
const EPS : Real = crate::math::DEFAULT_EPSILON;
const EPS: Real = crate::math::DEFAULT_EPSILON;

let vb = self.b - self.a;
let vc = self.c - self.a;
Expand Down Expand Up @@ -491,12 +506,11 @@ impl Triangle {
let c = vp.dot(&nb) * signed_clim.signum();
let clim = signed_clim.abs();

return
c >= 0.0 &&
c <= clim &&
b >= 0.0 &&
b <= blim &&
c * blim + b * clim <= blim * clim;
return c >= 0.0
&& c <= clim
&& b >= 0.0
&& b <= blim
&& c * blim + b * clim <= blim * clim;
}

/// The normal of the given feature of this shape.
Expand Down Expand Up @@ -548,7 +562,6 @@ impl Triangle {
}
}


impl SupportMap for Triangle {
#[inline]
fn local_support_point(&self, dir: &Vector<Real>) -> Point<Real> {
Expand Down Expand Up @@ -678,11 +691,53 @@ impl ConvexPolyhedron for Triangle {
}
*/

#[cfg(feature = "dim3")]
#[cfg(feature = "dim2")]
#[cfg(test)]
mod test {
use crate::math::Real;
use crate::shape::Triangle;
use na::Point3;

#[test]
fn test_triangle_area() {
let pa = Point2::new(5.0, 0.0);
let pb = Point2::new(0.0, 0.0);
let pc = Point2::new(0.0, 4.0);

assert!(relative_eq!(Triangle::new(pa, pb, pc).area(), 10.0));
}

#[test]
fn test_triangle_contains_point() {
let tri = Triangle::new(
Point2::new(5.0, 0.0),
Point2::new(0.0, 0.0),
Point2::new(0.0, 4.0),
);

assert!(tri.contains_point(&Point2::new(1.0, 1.0)));
assert!(!tri.contains_point(&Point2::new(-1.0, 1.0)));
}

#[test]
fn test_obtuse_triangle_contains_point() {
let tri = Triangle::new(
Point2::new(-10.0, 10.0),
Point2::new(0.0, 0.0),
Point2::new(20.0, 0.0),
);

assert!(tri.contains_point(&Point2::new(-3.0, 5.0)));
assert!(tri.contains_point(&Point2::new(5.0, 1.0)));
assert!(!tri.contains_point(&Point2::new(0.0, -1.0)));
}
}

#[cfg(feature = "dim3")]
#[cfg(test)]
mod test {
use crate::math::Real;
use crate::shape::Triangle;
use na::Point3;

#[test]
Expand Down Expand Up @@ -752,18 +807,25 @@ mod test {
// a number of points along a line intersecting the triangle.
for i in -50i16..150 {
let a = 0.15;
let b = 0.01 * Real::from(i); // b ranges from -0.5 to 1.5
let b = 0.01 * Real::from(i); // b ranges from -0.5 to 1.5
let c = 1.0 - a - b;
let p = o + (va * a + vb * b + vc * c);

match i {
ii if ii < 0 || ii > 85 =>
assert!(!tri.contains_point(&p), "Should not contain: i = {}, b = {}", i, b),
ii if ii > 0 && ii < 85 =>
assert!(tri.contains_point(&p), "Should contain: i = {}, b = {}", i, b),
_ => (), // Points at the edge may be seen as inside or outside
ii if ii < 0 || ii > 85 => assert!(
!tri.contains_point(&p),
"Should not contain: i = {}, b = {}",
i,
b
),
ii if ii > 0 && ii < 85 => assert!(
tri.contains_point(&p),
"Should contain: i = {}, b = {}",
i,
b
),
_ => (), // Points at the edge may be seen as inside or outside
}
}

}
}

0 comments on commit b37cedf

Please sign in to comment.