mesh_geometry/utils/
aabb.rs1use crate::{Float, Point3};
2
3#[derive(Debug, Clone, Copy, PartialEq)]
5pub struct Aabb<T: Float> {
6 pub min: Point3<T>,
8 pub max: Point3<T>,
10}
11
12impl<T: Float> Aabb<T> {
13 pub fn empty() -> Self {
15 let inf = T::infinity();
16 let neg = T::neg_infinity();
17 Aabb {
18 min: Point3::new(inf, inf, inf),
19 max: Point3::new(neg, neg, neg),
20 }
21 }
22
23 pub fn from_points(pts: &[Point3<T>]) -> Self {
25 let mut bb: Aabb<T> = Aabb::empty();
26 for &p in pts {
27 bb.min.x = bb.min.x.min(p.x);
28 bb.min.y = bb.min.y.min(p.y);
29 bb.min.z = bb.min.z.min(p.z);
30 bb.max.x = bb.max.x.max(p.x);
31 bb.max.y = bb.max.y.max(p.y);
32 bb.max.z = bb.max.z.max(p.z);
33 }
34 bb
35 }
36
37 pub fn grow(&mut self, p: Point3<T>) {
39 self.min.x = self.min.x.min(p.x);
40 self.min.y = self.min.y.min(p.y);
41 self.min.z = self.min.z.min(p.z);
42 self.max.x = self.max.x.max(p.x);
43 self.max.y = self.max.y.max(p.y);
44 self.max.z = self.max.z.max(p.z);
45 }
46
47 pub fn intersects(&self, other: &Aabb<T>) -> bool {
49 !(self.max.x < other.min.x ||
50 self.min.x > other.max.x ||
51 self.max.y < other.min.y ||
52 self.min.y > other.max.y ||
53 self.max.z < other.min.z ||
54 self.min.z > other.max.z)
55 }
56
57 pub fn contains(&self, p: Point3<T>) -> bool {
59 p.x >= self.min.x && p.x <= self.max.x &&
60 p.y >= self.min.y && p.y <= self.max.y &&
61 p.z >= self.min.z && p.z <= self.max.z
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68 use crate::Point3;
69
70 #[test]
71 fn aabb_from_and_contains() {
72 let pts = [
73 Point3::new(-1.0,2.0,0.0),
74 Point3::new(3.0,-2.0,5.0),
75 ];
76 let bb = Aabb::from_points(&pts);
77 assert!(bb.contains(Point3::new(0.0,0.0,2.5)));
78 assert!(!bb.contains(Point3::new(-2.0,0.0,0.0)));
79 }
80
81 #[test]
82 fn aabb_intersect() {
83 let b1 = Aabb {
84 min: Point3::new(0.0,0.0,0.0),
85 max: Point3::new(1.0,1.0,1.0),
86 };
87 let b2 = Aabb {
88 min: Point3::new(0.5,0.5,0.5),
89 max: Point3::new(2.0,2.0,2.0),
90 };
91 assert!(b1.intersects(&b2));
92 let b3 = Aabb {
93 min: Point3::new(2.0,2.0,2.0),
94 max: Point3::new(3.0,3.0,3.0),
95 };
96 assert!(!b1.intersects(&b3));
97 }
98}