Skip to main content

copc_core/
bounds.rs

1/// Axis-aligned XYZ bounds.
2#[derive(Clone, Copy, Debug, PartialEq)]
3pub struct Bounds {
4    pub min: (f64, f64, f64),
5    pub max: (f64, f64, f64),
6}
7
8impl Bounds {
9    pub fn new(min: (f64, f64, f64), max: (f64, f64, f64)) -> Self {
10        Self { min, max }
11    }
12
13    pub fn point(x: f64, y: f64, z: f64) -> Self {
14        Self {
15            min: (x, y, z),
16            max: (x, y, z),
17        }
18    }
19
20    pub fn cube(center: (f64, f64, f64), halfsize: f64) -> Self {
21        Self {
22            min: (
23                center.0 - halfsize,
24                center.1 - halfsize,
25                center.2 - halfsize,
26            ),
27            max: (
28                center.0 + halfsize,
29                center.1 + halfsize,
30                center.2 + halfsize,
31            ),
32        }
33    }
34
35    pub fn extend(&mut self, x: f64, y: f64, z: f64) {
36        self.min.0 = self.min.0.min(x);
37        self.min.1 = self.min.1.min(y);
38        self.min.2 = self.min.2.min(z);
39        self.max.0 = self.max.0.max(x);
40        self.max.1 = self.max.1.max(y);
41        self.max.2 = self.max.2.max(z);
42    }
43
44    pub fn center(self) -> (f64, f64, f64) {
45        (
46            (self.min.0 + self.max.0) * 0.5,
47            (self.min.1 + self.max.1) * 0.5,
48            (self.min.2 + self.max.2) * 0.5,
49        )
50    }
51
52    pub fn octant(self, octant: u8) -> Self {
53        let center = self.center();
54        let (min_x, max_x) = if octant & 1 == 0 {
55            (self.min.0, center.0)
56        } else {
57            (center.0, self.max.0)
58        };
59        let (min_y, max_y) = if octant & 2 == 0 {
60            (self.min.1, center.1)
61        } else {
62            (center.1, self.max.1)
63        };
64        let (min_z, max_z) = if octant & 4 == 0 {
65            (self.min.2, center.2)
66        } else {
67            (center.2, self.max.2)
68        };
69        Self {
70            min: (min_x, min_y, min_z),
71            max: (max_x, max_y, max_z),
72        }
73    }
74
75    pub fn intersects(self, other: Self) -> bool {
76        self.max.0 >= other.min.0
77            && self.min.0 <= other.max.0
78            && self.max.1 >= other.min.1
79            && self.min.1 <= other.max.1
80            && self.max.2 >= other.min.2
81            && self.min.2 <= other.max.2
82    }
83
84    pub fn contains_xyz(self, x: f64, y: f64, z: f64) -> bool {
85        self.min.0 <= x
86            && x <= self.max.0
87            && self.min.1 <= y
88            && y <= self.max.1
89            && self.min.2 <= z
90            && z <= self.max.2
91    }
92}