parry3d_f64/transformation/convex_hull3/
triangle_facet.rs1use 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 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 pub fn order_independent_can_be_seen_by_point(
103 &self,
104 point: usize,
105 points: &[Point3<Real>],
106 ) -> bool {
107 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}