pbrt_r3/core/geometry/
bounds2.rs1use super::Vector2;
2use crate::core::base::*;
3
4#[derive(Debug, PartialEq, Copy, Clone)]
5pub struct Bounds2<T> {
6 pub min: Vector2<T>,
7 pub max: Vector2<T>,
8}
9
10pub type Bounds2f = Bounds2<Float>;
11pub type Bounds2i = Bounds2<i32>;
12
13impl<T: Copy + PartialOrd> Bounds2<T> {
14 pub fn new(v0: &Vector2<T>, v1: &Vector2<T>) -> Self {
15 let min = Vector2::<T>::new(min_(v0.x, v1.x), min_(v0.y, v1.y));
16 let max = Vector2::<T>::new(max_(v0.x, v1.x), max_(v0.y, v1.y));
17 Bounds2::<T> { min, max }
18 }
19}
20
21fn min_<T: Copy + PartialOrd>(a: T, b: T) -> T {
22 return if a <= b { a } else { b };
23}
24
25fn max_<T: Copy + PartialOrd>(a: T, b: T) -> T {
26 return if a >= b { a } else { b };
27}
28
29impl<
30 T: Copy
31 + PartialOrd
32 + std::ops::Add<Output = T>
33 + std::ops::Sub<Output = T>
34 + std::ops::Mul<Output = T>
35 + std::ops::Div<Output = T>,
36 > Bounds2<T>
37{
38 pub fn area(&self) -> T {
39 return (self.max.x - self.min.x) * (self.max.y - self.min.y);
40 }
41 pub fn diagonal(&self) -> Vector2<T> {
42 return self.max - self.min;
43 }
44 pub fn offset(&self, p: &Vector2<T>) -> Vector2<T> {
45 let mut o = *p - self.min;
46 if self.max.x > self.min.x {
47 o.x = o.x / (self.max.x - self.min.x);
48 }
49 if self.max.y > self.min.y {
50 o.y = o.y / (self.max.y - self.min.y);
51 }
52 return o;
53 }
54
55 pub fn expand(&self, delta: T) -> Self {
56 let delta = Vector2::<T>::new(delta, delta);
57 return Bounds2 {
58 min: self.min - delta,
59 max: self.max + delta,
60 };
61 }
62
63 pub fn union(&self, other: &Self) -> Self {
64 let min = Vector2::<T>::new(min_(self.min.x, other.min.x), min_(self.min.y, other.min.y));
65 let max = Vector2::<T>::new(max_(self.max.x, other.max.x), max_(self.max.y, other.max.y));
66 return Bounds2 { min, max };
67 }
68
69 pub fn intersect(&self, other: &Self) -> Self {
70 let min = Vector2::<T>::new(max_(self.min.x, other.min.x), max_(self.min.y, other.min.y));
71 let max = Vector2::<T>::new(min_(self.max.x, other.max.x), min_(self.max.y, other.max.y));
72 return Bounds2 { min, max };
73 }
74
75 pub fn union_p(&self, other: &Vector2<T>) -> Self {
76 let min = Vector2::<T>::new(min_(self.min.x, other.x), min_(self.min.y, other.y));
77 let max = Vector2::<T>::new(max_(self.max.x, other.x), max_(self.max.y, other.y));
78 return Bounds2 { min, max };
79 }
80
81 pub fn inside(&self, p: &Vector2<T>) -> bool {
82 return p.x >= self.min.x && p.x <= self.max.x && p.y >= self.min.y && p.y <= self.max.y;
83 }
84
85 pub fn inside_exclusive(&self, p: &Vector2<T>) -> bool {
86 return p.x >= self.min.x && p.x < self.max.x && p.y >= self.min.y && p.y < self.max.y;
87 }
88}
89
90impl Bounds2f {
91 pub fn lerp(&self, t: &Vector2f) -> Vector2f {
92 return Vector2f::new(
93 lerp(t.x, self.min.x, self.max.x),
94 lerp(t.y, self.min.y, self.max.y),
95 );
96 }
97}
98
99impl<T: Copy + PartialOrd> From<((T, T), (T, T))> for Bounds2<T> {
100 fn from(value: ((T, T), (T, T))) -> Self {
101 let min = Vector2::<T>::from(value.0);
102 let max = Vector2::<T>::from(value.1);
103 Bounds2::<T>::new(&min, &max)
104 }
105}
106
107impl<T: Copy> From<(T, T)> for Bounds2<T> {
108 fn from(value: (T, T)) -> Self {
109 Bounds2::<T> {
110 min: Vector2::<T>::from(value),
111 max: Vector2::<T>::from(value),
112 }
113 }
114}
115
116pub struct Bounds2iIterator<'a> {
117 p: Point2i,
118 bounds: &'a Bounds2i,
119}
120
121impl<'a> Iterator for Bounds2iIterator<'a> {
122 type Item = Point2i;
123
124 fn next(&mut self) -> Option<Self::Item> {
125 if self.p.y < self.bounds.max.y && self.p.x < self.bounds.max.x {
126 let old = self.p;
127 self.p.x += 1;
128 if self.p.x == self.bounds.max.x {
129 self.p.x = self.bounds.min.x;
130 self.p.y += 1;
131 }
132 return Some(old);
133 } else {
134 return None;
135 }
136 }
137}
138
139impl<'a> IntoIterator for &'a Bounds2i {
140 type Item = Point2i;
141 type IntoIter = Bounds2iIterator<'a>;
142
143 fn into_iter(self) -> Self::IntoIter {
144 Bounds2iIterator {
145 p: self.min,
146 bounds: self,
147 }
148 }
149}
150
151impl Default for Bounds2i {
152 fn default() -> Self {
153 Bounds2i {
154 min: Point2i::new(std::i32::MAX, std::i32::MAX),
155 max: Point2i::new(std::i32::MIN, std::i32::MIN),
156 }
157 }
158}
159
160impl Default for Bounds2f {
161 fn default() -> Self {
162 Bounds2f {
163 min: Point2f::new(Float::MAX, Float::MAX),
164 max: Point2f::new(Float::MIN, Float::MIN),
165 }
166 }
167}
168
169#[cfg(test)]
170mod tests {
171 use super::*;
172
173 #[test]
174 fn test_001() {
175 let v1 = Vector2f::new(1.0, 2.0);
176 let v2 = Vector2f::new(4.0, 5.0);
177 let b1 = Bounds2f::new(&v1, &v2);
178 assert_eq!(b1.min, v1);
179 assert_eq!(b1.max, v2);
180 }
181}