1use super::traits::*;
2use super::vec::*;
3use std::fmt;
4
5#[repr(C)]
6#[derive(Clone, Debug, Eq, PartialEq)]
7pub struct BBox<T>
11where
12 T: Vector,
13{
14 min: T,
15 max: T,
16}
17
18pub type Box2i32 = BBox<V2i32>;
19pub type Box2f32 = BBox<V2f32>;
20pub type Box2f64 = BBox<V2f64>;
21pub type Box3i32 = BBox<V3i32>;
22pub type Box3f32 = BBox<V3f32>;
23pub type Box3f64 = BBox<V3f64>;
24
25impl<T> fmt::Display for BBox<T>
26where
27 T: Vector + fmt::Display,
28{
29 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
30 write!(f, "[{}, {}]", self.min, self.max)
31 }
32}
33
34impl<T> BBox<T>
35where
36 T: Vector,
37{
38 pub fn new() -> BBox<T> {
40 BBox::<T>::make_empty()
41 }
42
43 pub fn make_empty() -> BBox<T> {
45 BBox::<T> {
46 min: T::max_value(),
47 max: T::min_value(),
48 }
49 }
50
51 pub fn make_infinite() -> BBox<T> {
54 BBox::<T> {
55 min: T::min_value(),
56 max: T::max_value(),
57 }
58 }
59
60 pub fn extend_by_pnt(&self, point: T) -> BBox<T> {
63 BBox::<T> {
64 min: self.min.min(point),
65 max: self.max.max(point),
66 }
67 }
68
69 pub fn extend_by_box(&self, other: &BBox<T>) -> BBox<T> {
72 BBox::<T> {
73 min: self.min.min(other.min),
74 max: self.max.max(other.max),
75 }
76 }
77
78 pub fn size(&self) -> T
80 where
81 T: Vector,
82 {
83 self.max - self.min
84 }
85
86 pub fn center(&self) -> T
88 where
89 T: Vector,
90 {
91 self.min + (self.max - self.min) / (T::one() + T::one())
94 }
95
96 pub fn is_empty(&self) -> bool
98 where
99 T: Vector,
100 {
101 self.max < self.min
102 }
103
104 pub fn has_volume(&self) -> bool
106 where
107 T: Vector,
108 {
109 !self.is_empty()
110 }
111
112 pub fn is_infinite(&self) -> bool
114 where
115 T: Vector,
116 {
117 self.min == T::min_value() && self.max == T::max_value()
118 }
119
120 pub fn contains(&self, point: T) -> bool
122 where
123 T: Vector,
124 {
125 point >= self.min && point <= self.max
126 }
127}
128
129impl Box2i32 {
130 pub fn intersects(&self, other: &Box2i32) -> bool {
131 if other.max.x < self.min.x
132 || other.max.y < self.min.y
133 || other.min.x > self.max.x
134 || other.min.y > self.max.y
135 {
136 false
137 } else {
138 true
139 }
140 }
141}
142
143impl Box2f32 {
144 pub fn intersects(&self, other: &Box2f32) -> bool {
145 if other.max.x < self.min.x
146 || other.max.y < self.min.y
147 || other.min.x > self.max.x
148 || other.min.y > self.max.y
149 {
150 false
151 } else {
152 true
153 }
154 }
155}
156
157impl Box2f64 {
158 pub fn intersects(&self, other: &Box2f64) -> bool {
159 if other.max.x < self.min.x
160 || other.max.y < self.min.y
161 || other.min.x > self.max.x
162 || other.min.y > self.max.y
163 {
164 false
165 } else {
166 true
167 }
168 }
169}
170
171impl Box3i32 {
172 pub fn intersects(&self, other: &Box3i32) -> bool {
173 if other.max.x < self.min.x
174 || other.max.y < self.min.y
175 || other.max.z < self.max.z
176 || other.min.x > self.max.x
177 || other.min.y > self.max.y
178 || other.min.z > self.max.z
179 {
180 false
181 } else {
182 true
183 }
184 }
185}
186
187impl Box3f32 {
188 pub fn intersects(&self, other: &Box3f32) -> bool {
189 if other.max.x < self.min.x
190 || other.max.y < self.min.y
191 || other.max.z < self.max.z
192 || other.min.x > self.max.x
193 || other.min.y > self.max.y
194 || other.min.z > self.max.z
195 {
196 false
197 } else {
198 true
199 }
200 }
201}
202
203impl Box3f64 {
204 pub fn intersects(&self, other: &Box3f64) -> bool {
205 if other.max.x < self.min.x
206 || other.max.y < self.min.y
207 || other.max.z < self.max.z
208 || other.min.x > self.max.x
209 || other.min.y > self.max.y
210 || other.min.z > self.max.z
211 {
212 false
213 } else {
214 true
215 }
216 }
217}
218
219#[test]
220fn test_bbox() {
221 let b21 = Box2f32::new();
222 assert!(b21.is_empty());
223
224 let v21 = V2f32 { x: -1.0, y: -1.0 };
225 let v22 = V2f32 { x: 1.0, y: 1.0 };
226 let b22 = b21.extend_by_pnt(v21);
227 println!("b22: {}", b22);
228 assert!(b22.has_volume());
229 assert!(!b22.is_infinite());
230 assert!(b22.min == v21 && b22.max == v21);
231 let b23 = b22.extend_by_pnt(v22);
232 assert!(b23.min == v21 && b23.max == v22);
233
234 let b24 = Box2f32 {
235 min: V2f32 { x: 2.0, y: 2.0 },
236 max: V2f32 { x: 3.0, y: 3.0 },
237 };
238 let b25 = Box2f32 {
239 min: V2f32 { x: 0.0, y: 0.0 },
240 max: V2f32 { x: 3.0, y: 3.0 },
241 };
242 assert!(!b23.intersects(&b24));
243 assert!(b23.intersects(&b25));
244 assert!(b25.contains(v22));
245
246 let b28 = Box2f32 {
247 min: V2f32 { x: -1.0, y: -1.0 },
248 max: V2f32 { x: 3.0, y: 3.0 },
249 };
250
251 let b29 = Box2f32 {
252 min: V2f32 { x: 0.0, y: 0.0 },
253 max: V2f32 { x: 2.0, y: 2.0 },
254 };
255
256 assert!(b28.intersects(&b29));
257
258 let b26 = b23.extend_by_box(&b25);
259 assert!(b26.size() == V2f32 { x: 4.0, y: 4.0 });
260 assert!(b26.center() == V2f32 { x: 1.0, y: 1.0 });
261
262 let b27 = Box2f32::make_infinite();
263 assert!(b27.is_infinite());
264}