parry2d/utils/
point_in_triangle.rs1use crate::math::{Real, Vector};
4
5#[derive(Eq, PartialEq, Debug, Copy, Clone)]
6pub enum Orientation {
8 Ccw,
10 Cw,
12 None,
14}
15
16pub fn corner_direction(p1: Vector, p2: Vector, p3: Vector) -> Orientation {
32 let v1 = p1 - p2;
33 let v2 = p3 - p2;
34 let cross: Real = v1.perp_dot(v2);
35
36 match cross
37 .partial_cmp(&0.0)
38 .expect("Found NaN while computing corner direction.")
39 {
40 core::cmp::Ordering::Less => Orientation::Ccw,
41 core::cmp::Ordering::Equal => Orientation::None,
42 core::cmp::Ordering::Greater => Orientation::Cw,
43 }
44}
45
46pub fn is_point_in_triangle(p: Vector, v1: Vector, v2: Vector, v3: Vector) -> Option<bool> {
49 let d1 = corner_direction(p, v1, v2);
50 let d2 = corner_direction(p, v2, v3);
51 let d3 = corner_direction(p, v3, v1);
52
53 let has_cw = d1 == Orientation::Cw || d2 == Orientation::Cw || d3 == Orientation::Cw;
54 let has_ccw = d1 == Orientation::Ccw || d2 == Orientation::Ccw || d3 == Orientation::Ccw;
55
56 if d1 == Orientation::None && d2 == Orientation::None && d3 == Orientation::None {
57 None
58 } else {
59 Some(!(has_cw && has_ccw))
60 }
61}