1use crate::linalg::{Vec2, Vec3, Mat3x4};
10
11#[derive(Clone, Copy, Debug, PartialEq)]
16pub struct Box {
17 pub min: Vec3,
18 pub max: Vec3,
19}
20
21impl Default for Box {
22 fn default() -> Self {
23 Box {
24 min: Vec3::splat(f64::INFINITY),
25 max: Vec3::splat(f64::NEG_INFINITY),
26 }
27 }
28}
29
30impl Box {
31 pub fn new() -> Self {
33 Self::default()
34 }
35
36 pub fn from_points(p1: Vec3, p2: Vec3) -> Self {
38 Box {
39 min: Vec3::new(p1.x.min(p2.x), p1.y.min(p2.y), p1.z.min(p2.z)),
40 max: Vec3::new(p1.x.max(p2.x), p1.y.max(p2.y), p1.z.max(p2.z)),
41 }
42 }
43
44 pub fn from_point(p: Vec3) -> Self {
46 Box { min: p, max: p }
47 }
48
49 pub fn is_empty(&self) -> bool {
51 self.min.x > self.max.x || self.min.y > self.max.y || self.min.z > self.max.z
52 }
53
54 pub fn size(&self) -> Vec3 {
55 self.max - self.min
56 }
57
58 pub fn center(&self) -> Vec3 {
59 (self.max + self.min) * 0.5
60 }
61
62 pub fn scale(&self) -> f64 {
64 let abs_min = Vec3::new(self.min.x.abs(), self.min.y.abs(), self.min.z.abs());
65 let abs_max = Vec3::new(self.max.x.abs(), self.max.y.abs(), self.max.z.abs());
66 let m = Vec3::new(
67 abs_min.x.max(abs_max.x),
68 abs_min.y.max(abs_max.y),
69 abs_min.z.max(abs_max.z),
70 );
71 m.x.max(m.y).max(m.z)
72 }
73
74 pub fn contains_point(&self, p: Vec3) -> bool {
75 p.x >= self.min.x && p.x <= self.max.x
76 && p.y >= self.min.y && p.y <= self.max.y
77 && p.z >= self.min.z && p.z <= self.max.z
78 }
79
80 pub fn contains_box(&self, other: &Box) -> bool {
81 other.min.x >= self.min.x && other.max.x <= self.max.x
82 && other.min.y >= self.min.y && other.max.y <= self.max.y
83 && other.min.z >= self.min.z && other.max.z <= self.max.z
84 }
85
86 pub fn union_point(&mut self, p: Vec3) {
88 self.min.x = self.min.x.min(p.x);
89 self.min.y = self.min.y.min(p.y);
90 self.min.z = self.min.z.min(p.z);
91 self.max.x = self.max.x.max(p.x);
92 self.max.y = self.max.y.max(p.y);
93 self.max.z = self.max.z.max(p.z);
94 }
95
96 pub fn union_box(&self, other: &Box) -> Box {
98 Box {
99 min: Vec3::new(
100 self.min.x.min(other.min.x),
101 self.min.y.min(other.min.y),
102 self.min.z.min(other.min.z),
103 ),
104 max: Vec3::new(
105 self.max.x.max(other.max.x),
106 self.max.y.max(other.max.y),
107 self.max.z.max(other.max.z),
108 ),
109 }
110 }
111
112 pub fn transform(&self, t: &Mat3x4) -> Box {
114 use crate::linalg::Vec4 as V4;
115 let min_t = *t * V4::new(self.min.x, self.min.y, self.min.z, 1.0);
116 let max_t = *t * V4::new(self.max.x, self.max.y, self.max.z, 1.0);
117 Box {
118 min: Vec3::new(min_t.x.min(max_t.x), min_t.y.min(max_t.y), min_t.z.min(max_t.z)),
119 max: Vec3::new(min_t.x.max(max_t.x), min_t.y.max(max_t.y), min_t.z.max(max_t.z)),
120 }
121 }
122
123 pub fn does_overlap_box(&self, other: &Box) -> bool {
124 self.min.x <= other.max.x && self.min.y <= other.max.y && self.min.z <= other.max.z
125 && self.max.x >= other.min.x && self.max.y >= other.min.y && self.max.z >= other.min.z
126 }
127
128 pub fn does_overlap_point_xy(&self, p: Vec3) -> bool {
130 p.x >= self.min.x && p.x <= self.max.x && p.y >= self.min.y && p.y <= self.max.y
131 }
132
133 pub fn is_finite(&self) -> bool {
134 self.min.x.is_finite() && self.min.y.is_finite() && self.min.z.is_finite()
135 && self.max.x.is_finite() && self.max.y.is_finite() && self.max.z.is_finite()
136 }
137}
138
139impl std::ops::Add<Vec3> for Box {
140 type Output = Box;
141 fn add(self, shift: Vec3) -> Box {
142 Box { min: self.min + shift, max: self.max + shift }
143 }
144}
145impl std::ops::AddAssign<Vec3> for Box {
146 fn add_assign(&mut self, shift: Vec3) {
147 self.min = self.min + shift;
148 self.max = self.max + shift;
149 }
150}
151impl std::ops::Mul<Vec3> for Box {
152 type Output = Box;
153 fn mul(self, scale: Vec3) -> Box {
154 Box { min: self.min * scale, max: self.max * scale }
155 }
156}
157impl std::ops::MulAssign<Vec3> for Box {
158 fn mul_assign(&mut self, scale: Vec3) {
159 self.min = self.min * scale;
160 self.max = self.max * scale;
161 }
162}
163
164#[derive(Clone, Copy, Debug, PartialEq)]
169pub struct Rect {
170 pub min: Vec2,
171 pub max: Vec2,
172}
173
174impl Default for Rect {
175 fn default() -> Self {
176 Rect {
177 min: Vec2::splat(f64::INFINITY),
178 max: Vec2::splat(f64::NEG_INFINITY),
179 }
180 }
181}
182
183impl Rect {
184 pub fn new() -> Self {
185 Self::default()
186 }
187
188 pub fn from_points(a: Vec2, b: Vec2) -> Self {
189 Rect {
190 min: Vec2::new(a.x.min(b.x), a.y.min(b.y)),
191 max: Vec2::new(a.x.max(b.x), a.y.max(b.y)),
192 }
193 }
194
195 pub fn size(&self) -> Vec2 {
196 self.max - self.min
197 }
198
199 pub fn area(&self) -> f64 {
200 let sz = self.size();
201 sz.x * sz.y
202 }
203
204 pub fn scale(&self) -> f64 {
205 let abs_min = Vec2::new(self.min.x.abs(), self.min.y.abs());
206 let abs_max = Vec2::new(self.max.x.abs(), self.max.y.abs());
207 let m = Vec2::new(abs_min.x.max(abs_max.x), abs_min.y.max(abs_max.y));
208 m.x.max(m.y)
209 }
210
211 pub fn center(&self) -> Vec2 {
212 (self.max + self.min) * 0.5
213 }
214
215 pub fn contains_point(&self, p: Vec2) -> bool {
216 p.x >= self.min.x && p.x <= self.max.x && p.y >= self.min.y && p.y <= self.max.y
217 }
218
219 pub fn contains_rect(&self, other: &Rect) -> bool {
220 other.min.x >= self.min.x && other.max.x <= self.max.x
221 && other.min.y >= self.min.y && other.max.y <= self.max.y
222 }
223
224 pub fn does_overlap(&self, other: &Rect) -> bool {
225 self.min.x <= other.max.x && self.min.y <= other.max.y
226 && self.max.x >= other.min.x && self.max.y >= other.min.y
227 }
228
229 pub fn is_empty(&self) -> bool {
230 self.max.y <= self.min.y || self.max.x <= self.min.x
231 }
232
233 pub fn is_finite(&self) -> bool {
234 self.min.x.is_finite() && self.min.y.is_finite()
235 && self.max.x.is_finite() && self.max.y.is_finite()
236 }
237
238 pub fn union_point(&mut self, p: Vec2) {
239 self.min.x = self.min.x.min(p.x);
240 self.min.y = self.min.y.min(p.y);
241 self.max.x = self.max.x.max(p.x);
242 self.max.y = self.max.y.max(p.y);
243 }
244
245 pub fn union_rect(&self, other: &Rect) -> Rect {
246 Rect {
247 min: Vec2::new(self.min.x.min(other.min.x), self.min.y.min(other.min.y)),
248 max: Vec2::new(self.max.x.max(other.max.x), self.max.y.max(other.max.y)),
249 }
250 }
251}
252
253impl std::ops::Add<Vec2> for Rect {
254 type Output = Rect;
255 fn add(self, shift: Vec2) -> Rect {
256 Rect { min: self.min + shift, max: self.max + shift }
257 }
258}
259impl std::ops::AddAssign<Vec2> for Rect {
260 fn add_assign(&mut self, shift: Vec2) {
261 self.min = self.min + shift;
262 self.max = self.max + shift;
263 }
264}
265impl std::ops::Mul<Vec2> for Rect {
266 type Output = Rect;
267 fn mul(self, scale: Vec2) -> Rect {
268 Rect { min: self.min * scale, max: self.max * scale }
269 }
270}
271impl std::ops::MulAssign<Vec2> for Rect {
272 fn mul_assign(&mut self, scale: Vec2) {
273 self.min = self.min * scale;
274 self.max = self.max * scale;
275 }
276}