parry3d_f64/transformation/convex_hull3/
triangle_facet.rs

1use crate::math::Real;
2use crate::shape::Triangle;
3use alloc::vec::Vec;
4use na::{Point3, Vector3};
5use num::Bounded;
6
7#[derive(Debug)]
8pub struct TriangleFacet {
9    pub valid: bool,
10    pub affinely_dependent: bool,
11    pub normal: Vector3<Real>,
12    pub adj: [usize; 3],
13    pub indirect_adj_id: [usize; 3],
14    pub pts: [usize; 3],
15    pub visible_points: Vec<usize>,
16    pub furthest_point: usize,
17    pub furthest_distance: Real,
18}
19
20impl TriangleFacet {
21    pub fn new(p1: usize, p2: usize, p3: usize, points: &[Point3<Real>]) -> TriangleFacet {
22        let p1p2 = points[p2] - points[p1];
23        let p1p3 = points[p3] - points[p1];
24
25        let normal = p1p2.cross(&p1p3).normalize();
26
27        TriangleFacet {
28            valid: true,
29            affinely_dependent: Triangle::new(points[p1], points[p2], points[p3])
30                .is_affinely_dependent(),
31            normal,
32            adj: [0, 0, 0],
33            indirect_adj_id: [0, 0, 0],
34            pts: [p1, p2, p3],
35            visible_points: Vec::new(),
36            furthest_point: Bounded::max_value(),
37            furthest_distance: 0.0,
38        }
39    }
40
41    pub fn add_visible_point(&mut self, pid: usize, points: &[Point3<Real>]) {
42        let distance = self.distance_to_point(pid, points);
43        assert!(distance > crate::math::DEFAULT_EPSILON);
44
45        if distance > self.furthest_distance {
46            self.furthest_distance = distance;
47            self.furthest_point = pid;
48        }
49
50        self.visible_points.push(pid);
51    }
52
53    pub fn distance_to_point(&self, point: usize, points: &[Point3<Real>]) -> Real {
54        self.normal.dot(&(points[point] - points[self.pts[0]]))
55    }
56
57    pub fn set_facets_adjascency(
58        &mut self,
59        adj1: usize,
60        adj2: usize,
61        adj3: usize,
62        id_adj1: usize,
63        id_adj2: usize,
64        id_adj3: usize,
65    ) {
66        self.indirect_adj_id[0] = id_adj1;
67        self.indirect_adj_id[1] = id_adj2;
68        self.indirect_adj_id[2] = id_adj3;
69
70        self.adj[0] = adj1;
71        self.adj[1] = adj2;
72        self.adj[2] = adj3;
73    }
74
75    pub fn first_point_from_edge(&self, id: usize) -> usize {
76        self.pts[id]
77    }
78
79    pub fn second_point_from_edge(&self, id: usize) -> usize {
80        self.pts[(id + 1) % 3]
81    }
82
83    pub fn can_see_point(&self, point: usize, points: &[Point3<Real>]) -> bool {
84        // An affinely-dependent triangle cannot see any point.
85        if self.affinely_dependent {
86            return false;
87        }
88
89        let p0 = points[self.pts[0]];
90        let pt = points[point];
91
92        if (pt - p0).dot(&self.normal) < crate::math::DEFAULT_EPSILON * 100.0 {
93            return false;
94        }
95
96        true
97    }
98
99    // Check that a given point can see this triangle,
100    // making sure that the order of the three indices of
101    // this triangle don't affect the test result.
102    pub fn order_independent_can_be_seen_by_point(
103        &self,
104        point: usize,
105        points: &[Point3<Real>],
106    ) -> bool {
107        // An affinely-dependent triangle can be seen by any point.
108        if self.affinely_dependent {
109            return true;
110        }
111
112        for i in 0..3 {
113            let p0 = points[self.pts[i]];
114            let pt = points[point];
115
116            if (pt - p0).dot(&self.normal) >= 0.0 {
117                return true;
118            }
119        }
120
121        false
122    }
123}