1use crate::Plane;
2use mini_math::{Point, Vector3};
3
4#[derive(Debug)]
6pub struct Triangle {
7 pub a: Point,
8 pub b: Point,
9 pub c: Point,
10}
11
12impl Triangle {
13 pub fn new(a: Point, b: Point, c: Point) -> Self {
15 Self { a, b, c }
16 }
17
18 pub(crate) fn barycentric_coordinates(&self, p: Point) -> Vector3 {
20 let e0 = self.b - self.a;
21 let e1 = self.c - self.a;
22 let e2 = p - self.a;
23
24 let d00 = e0.dot(e0);
25 let d01 = e0.dot(e1);
26 let d11 = e1.dot(e1);
27 let d20 = e2.dot(e0);
28 let d21 = e2.dot(e1);
29 let denom = 1.0 / (d00 * d11 - d01 * d01);
30 let v = (d11 * d20 - d01 * d21) * denom;
31 let w = (d00 * d21 - d01 * d20) * denom;
32 let u = 1.0 - v - w;
33
34 Vector3::new(u, v, w)
35 }
36
37 pub(crate) fn coplanar_point_inside(&self, p: Point) -> bool {
39 let plane = Plane::from(self);
40
41 let edge_cross = (self.b - self.a).cross(p - self.a);
42 if plane.normal.dot(edge_cross) > 0.0 {
44 return false;
45 }
46
47 let edge_cross = (self.c - self.b).cross(p - self.b);
48 if plane.normal.dot(edge_cross) > 0.0 {
50 return false;
51 }
52
53 let edge_cross = (self.a - self.c).cross(p - self.c);
54 if plane.normal.dot(edge_cross) > 0.0 {
56 return false;
57 }
58
59 true
60 }
61}