fenris_geometry/primitives/
hexahedron.rs1use crate::{
2 AxisAlignedBoundingBox, BoundedGeometry, ConvexPolyhedron, Distance, Quad3d, SignedDistance, SignedDistanceResult,
3};
4use fenris_traits::Real;
5use nalgebra::{OPoint, Point3, Scalar, U3};
6use numeric_literals::replace_float_literals;
7
8#[derive(Debug, Copy, Clone, PartialEq, Hash)]
9pub struct Hexahedron<T>
10where
11 T: Scalar,
12{
13 vertices: [Point3<T>; 8],
15}
16
17impl<T> BoundedGeometry<T> for Hexahedron<T>
18where
19 T: Real,
20{
21 type Dimension = U3;
22
23 fn bounding_box(&self) -> AxisAlignedBoundingBox<T, U3> {
24 AxisAlignedBoundingBox::from_points(&self.vertices).unwrap()
25 }
26}
27
28impl<T> Hexahedron<T>
29where
30 T: Scalar,
31{
32 pub fn from_vertices(vertices: [Point3<T>; 8]) -> Self {
33 Self { vertices }
34 }
35}
36
37impl<T> Hexahedron<T>
38where
39 T: Real,
40{
41 #[replace_float_literals(T::from_f64(literal).unwrap())]
42 pub fn reference() -> Self {
43 Self::from_vertices([
44 Point3::new(-1.0, -1.0, -1.0),
45 Point3::new(1.0, -1.0, -1.0),
46 Point3::new(1.0, 1.0, -1.0),
47 Point3::new(-1.0, 1.0, -1.0),
48 Point3::new(-1.0, -1.0, 1.0),
49 Point3::new(1.0, -1.0, 1.0),
50 Point3::new(1.0, 1.0, 1.0),
51 Point3::new(-1.0, 1.0, 1.0),
52 ])
53 }
54}
55
56impl<T> Distance<T, Point3<T>> for Hexahedron<T>
57where
58 T: Real,
59{
60 fn distance(&self, point: &Point3<T>) -> T {
61 let signed_dist = self.compute_signed_distance(point).signed_distance;
62 T::max(signed_dist, T::zero())
63 }
64}
65
66impl<T> SignedDistance<T, U3> for Hexahedron<T>
67where
68 T: Real,
69{
70 fn query_signed_distance(&self, point: &OPoint<T, U3>) -> Option<SignedDistanceResult<T, U3>> {
71 Some(self.compute_signed_distance(point))
72 }
73}
74
75impl<'a, T> ConvexPolyhedron<'a, T> for Hexahedron<T>
76where
77 T: Real,
78{
79 type Face = Quad3d<T>;
80
81 fn num_faces(&self) -> usize {
82 6
83 }
84
85 fn get_face(&self, index: usize) -> Option<Self::Face> {
86 let v = &self.vertices;
87 let quad = |i, j, k, l| Some(Quad3d::from_vertices([v[i], v[j], v[k], v[l]]));
88
89 match index {
91 0 => quad(0, 1, 2, 3),
92 1 => quad(4, 5, 1, 0),
93 2 => quad(5, 6, 2, 1),
94 3 => quad(6, 7, 3, 2),
95 4 => quad(0, 3, 7, 4),
96 5 => quad(4, 7, 6, 5),
97 _ => None,
98 }
99 }
100}