use crate::math::{Point, Real};
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
pub enum Orientation {
Ccw,
Cw,
None,
}
pub fn corner_direction(p1: &Point<Real>, p2: &Point<Real>, p3: &Point<Real>) -> Orientation {
let v1 = p1 - p2;
let v2 = p3 - p2;
let cross: Real = v1.perp(&v2);
match cross
.partial_cmp(&0.0)
.expect("Found NaN while computing corner direction.")
{
std::cmp::Ordering::Less => Orientation::Ccw,
std::cmp::Ordering::Equal => Orientation::None,
std::cmp::Ordering::Greater => Orientation::Cw,
}
}
pub fn is_point_in_triangle(
p: &Point<Real>,
v1: &Point<Real>,
v2: &Point<Real>,
v3: &Point<Real>,
) -> Option<bool> {
let d1 = corner_direction(p, v1, v2);
let d2 = corner_direction(p, v2, v3);
let d3 = corner_direction(p, v3, v1);
let has_cw = d1 == Orientation::Cw || d2 == Orientation::Cw || d3 == Orientation::Cw;
let has_ccw = d1 == Orientation::Ccw || d2 == Orientation::Ccw || d3 == Orientation::Ccw;
if d1 == Orientation::None && d2 == Orientation::None && d3 == Orientation::None {
None
} else {
Some(!(has_cw && has_ccw))
}
}