pbrt_r3/core/geometry/
vector2.rs1use super::numeric_traits::*;
2use std::ops;
3
4#[derive(Debug, PartialEq, Default, Copy, Clone)]
5pub struct Vector2<T> {
6 pub x: T,
7 pub y: T,
8}
9
10impl<T: Copy> Vector2<T> {
11 pub fn new(x: T, y: T) -> Self {
12 Vector2::<T> { x, y }
13 }
14}
15
16impl<T: Default> Vector2<T> {
17 #[inline]
18 pub fn zero() -> Self {
19 Vector2::<T> {
20 x: T::default(),
21 y: T::default(),
22 }
23 }
24}
25
26impl<T: Copy + NumberType> Vector2<T> {
27 #[inline]
28 pub fn abs(&self) -> Self {
29 Vector2::<T> {
30 x: NumberType::abs(self.x),
31 y: NumberType::abs(self.y),
32 }
33 }
34}
35
36impl<
37 T: Copy
38 + PartialEq
39 + FloatType
40 + NumberType
41 + std::ops::Add<Output = T>
42 + std::ops::Sub<Output = T>
43 + std::ops::Mul<Output = T>
44 + std::ops::Div<Output = T>
45 + std::ops::MulAssign<T>,
46 > Vector2<T>
47{
48 #[inline]
49 pub fn abs_dot(&self, rhs: &Self) -> T {
50 return NumberType::abs(self.dot(rhs));
51 }
52}
53
54impl<
55 T: Copy
56 + FloatType
57 + std::ops::Add<Output = T>
58 + std::ops::Sub<Output = T>
59 + std::ops::Mul<Output = T>
60 + std::ops::Div<Output = T>
61 + std::ops::MulAssign<T>,
62 > Vector2<T>
63{
64 #[inline]
65 pub fn dot(&self, rhs: &Self) -> T {
66 return self.x * rhs.x + self.y * rhs.y;
67 }
68
69 #[inline]
70 pub fn length_squared(&self) -> T {
71 return self.dot(self);
72 }
73
74 #[inline]
75 pub fn length(&self) -> T {
76 return FloatType::sqrt(self.x * self.x + self.y * self.y);
77 }
78
79 #[inline]
80 pub fn normalize(&self) -> Self {
81 let l = self.length();
82 Vector2::<T> {
83 x: self.x / l,
84 y: self.y / l,
85 }
86 }
87
88 #[inline]
89 pub fn distance_squared(a: &Self, b: &Self) -> T {
90 let v = *a - *b;
91 return v.dot(&v);
92 }
93
94 #[inline]
95 pub fn distance(a: &Self, b: &Self) -> T {
96 return FloatType::sqrt(Self::distance_squared(a, b));
97 }
98
99 #[inline]
100 pub fn mul_assign(&mut self, f: T) {
101 self.x *= f;
102 self.y *= f;
103 }
104}
105
106impl<T: std::ops::Add<Output = T>> ops::Add<Vector2<T>> for Vector2<T> {
108 type Output = Vector2<T>;
109 #[inline]
110 fn add(self, rhs: Vector2<T>) -> Vector2<T> {
111 return Vector2 {
112 x: self.x + rhs.x,
113 y: self.y + rhs.y,
114 };
115 }
116}
117
118impl<T: std::ops::Sub<Output = T>> ops::Sub<Vector2<T>> for Vector2<T> {
120 type Output = Vector2<T>;
121 #[inline]
122 fn sub(self, rhs: Vector2<T>) -> Vector2<T> {
123 return Vector2 {
124 x: self.x - rhs.x,
125 y: self.y - rhs.y,
126 };
127 }
128}
129
130impl<T: std::ops::Mul<Output = T>> ops::Mul<Vector2<T>> for Vector2<T> {
133 type Output = Vector2<T>;
134 #[inline]
135 fn mul(self, rhs: Vector2<T>) -> Vector2<T> {
136 return Vector2 {
137 x: self.x * rhs.x,
138 y: self.y * rhs.y,
139 };
140 }
141}
142
143impl<T: std::ops::Mul<Output = T> + Copy> ops::Mul<T> for Vector2<T> {
146 type Output = Vector2<T>;
147 #[inline]
148 fn mul(self, rhs: T) -> Vector2<T> {
149 return Vector2 {
150 x: self.x * rhs,
151 y: self.y * rhs,
152 };
153 }
154}
155
156impl<T: std::ops::Div<Output = T> + Copy> ops::Div<T> for Vector2<T> {
157 type Output = Vector2<T>;
158 #[inline]
159 fn div(self, rhs: T) -> Vector2<T> {
160 return Vector2 {
161 x: self.x / rhs,
162 y: self.y / rhs,
163 };
164 }
165}
166
167impl ops::Mul<Vector2<f32>> for f32 {
168 type Output = Vector2<f32>;
169 #[inline]
170 fn mul(self, rhs: Vector2<f32>) -> Vector2<f32> {
171 return Vector2 {
172 x: self * rhs.x,
173 y: self * rhs.y,
174 };
175 }
176}
177
178impl ops::Mul<Vector2<f64>> for f64 {
179 type Output = Vector2<f64>;
180 #[inline]
181 fn mul(self, rhs: Vector2<f64>) -> Vector2<f64> {
182 return Vector2 {
183 x: self * rhs.x,
184 y: self * rhs.y,
185 };
186 }
187}
188
189impl ops::Mul<Vector2<i32>> for i32 {
190 type Output = Vector2<i32>;
191 #[inline]
192 fn mul(self, rhs: Vector2<i32>) -> Vector2<i32> {
193 return Vector2 {
194 x: self * rhs.x,
195 y: self * rhs.y,
196 };
197 }
198}
199
200impl<T: std::ops::Neg<Output = T>> ops::Neg for Vector2<T> {
201 type Output = Self;
202 #[inline]
203 fn neg(self) -> Self::Output {
204 return Vector2 {
205 x: -self.x,
206 y: -self.y,
207 };
208 }
209}
210
211impl<T: std::ops::AddAssign<T>> ops::AddAssign for Vector2<T> {
212 #[inline]
213 fn add_assign(&mut self, rhs: Self) {
214 self.x += rhs.x;
215 self.y += rhs.y;
216 }
217}
218
219impl<T: std::ops::SubAssign<T>> ops::SubAssign for Vector2<T> {
220 #[inline]
221 fn sub_assign(&mut self, rhs: Self) {
222 self.x -= rhs.x;
223 self.y -= rhs.y;
224 }
225}
226
227impl<T: std::ops::MulAssign<T>> ops::MulAssign for Vector2<T> {
228 #[inline]
229 fn mul_assign(&mut self, rhs: Self) {
230 self.x *= rhs.x;
231 self.y *= rhs.y;
232 }
233}
234
235impl<T: std::ops::MulAssign<T> + Copy> ops::MulAssign<T> for Vector2<T> {
236 #[inline]
237 fn mul_assign(&mut self, rhs: T) {
238 self.x *= rhs;
239 self.y *= rhs;
240 }
241}
242
243impl<T: std::ops::DivAssign<T>> ops::DivAssign<Vector2<T>> for Vector2<T> {
244 #[inline]
245 fn div_assign(&mut self, rhs: Self) {
246 self.x /= rhs.x;
247 self.y /= rhs.y;
248 }
249}
250
251impl<T: std::ops::DivAssign<T> + Copy> ops::DivAssign<T> for Vector2<T> {
252 #[inline]
253 fn div_assign(&mut self, rhs: T) {
254 self.x /= rhs;
255 self.y /= rhs;
256 }
257}
258
259impl<T> ops::Index<usize> for Vector2<T> {
260 type Output = T;
261 #[inline]
262 fn index(&self, i: usize) -> &Self::Output {
263 match i {
264 0 => &self.x,
265 _ => &self.y,
266 }
267 }
268}
269
270impl<T> ops::IndexMut<usize> for Vector2<T> {
271 #[inline]
272 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
273 match i {
274 0 => &mut self.x,
275 _ => &mut self.y,
276 }
277 }
278}
279
280impl<T: Copy> From<T> for Vector2<T> {
281 #[inline]
282 fn from(value: T) -> Self {
283 Vector2::<T>::new(value, value)
284 }
285}
286
287impl<T: Copy> From<(T, T)> for Vector2<T> {
288 #[inline]
289 fn from(value: (T, T)) -> Self {
290 Vector2::<T>::new(value.0, value.1)
291 }
292}
293
294impl<T: Copy> From<[T; 2]> for Vector2<T> {
295 #[inline]
296 fn from(value: [T; 2]) -> Self {
297 Vector2::<T>::new(value[0], value[1])
298 }
299}
300
301impl<T: Copy> From<&[T]> for Vector2<T> {
302 #[inline]
303 fn from(value: &[T]) -> Self {
304 Vector2::<T>::new(value[0], value[1])
305 }
306}
307
308#[cfg(test)]
310mod tests {
311 use super::*;
312
313 #[test]
314 fn test_001() {
315 type Vector2f = Vector2<f32>;
316 let v1 = Vector2f::new(1.0, 2.0);
317 let v2 = Vector2f::new(3.0, 4.0);
318 let v3 = v1 + v2;
319 let v4 = Vector2f::new(4.0, 6.0);
320 assert_eq!(v3, v4);
321 }
322
323 #[test]
324 fn test_002() {
325 type Vector2f = Vector2<f32>;
326 let v1 = Vector2f::new(1.0, 2.0);
327 let v2 = Vector2f::new(3.0, 4.0);
328 let v3 = v2 - v1;
329 let v4 = Vector2f::new(2.0, 2.0);
330 assert_eq!(v3, v4);
331 }
332
333 #[test]
334 fn test_003() {
335 type Vector2f = Vector2<f32>;
336 let v1 = Vector2f::new(1.0, 2.0);
337 let v2 = Vector2f::new(3.0, 4.0);
338 let v3 = v2 * v1;
339 let v4 = Vector2f::new(3.0, 8.0);
340 assert_eq!(v3, v4);
341 }
342}