pbrt_r3/core/geometry/
vector3.rs

1use super::numeric_traits::*;
2use std::ops;
3
4#[derive(Debug, PartialEq, Default, Copy, Clone)]
5pub struct Vector3<T> {
6    pub x: T,
7    pub y: T,
8    pub z: T,
9}
10
11impl<T: Copy> Vector3<T> {
12    pub fn new(x: T, y: T, z: T) -> Self {
13        Vector3::<T> { x, y, z }
14    }
15}
16
17impl<T: Copy + Default> Vector3<T> {
18    #[inline]
19    pub fn zero() -> Self {
20        Vector3::<T> {
21            x: T::default(),
22            y: T::default(),
23            z: T::default(),
24        }
25    }
26}
27
28impl<T: Copy + NumberType> Vector3<T> {
29    #[inline]
30    pub fn abs(&self) -> Self {
31        Vector3::<T> {
32            x: NumberType::abs(self.x),
33            y: NumberType::abs(self.y),
34            z: NumberType::abs(self.z),
35        }
36    }
37}
38
39impl<
40        T: Copy
41            + PartialEq
42            + FloatType
43            + NumberType
44            + std::ops::Add<Output = T>
45            + std::ops::Sub<Output = T>
46            + std::ops::Mul<Output = T>
47            + std::ops::Div<Output = T>
48            + std::ops::MulAssign<T>,
49    > Vector3<T>
50{
51    #[inline]
52    pub fn abs_dot(&self, rhs: &Self) -> T {
53        return NumberType::abs(self.dot(rhs));
54    }
55}
56
57impl<
58        T: Copy
59            + PartialEq
60            + PartialOrd
61            + FloatType
62            + NumberType
63            + Default
64            + std::ops::Neg<Output = T>
65            + std::ops::Add<Output = T>
66            + std::ops::Sub<Output = T>
67            + std::ops::Mul<Output = T>
68            + std::ops::Div<Output = T>
69            + std::ops::MulAssign<T>,
70    > Vector3<T>
71{
72    pub fn coordinate_system(d1: &Self) -> (Self, Self, Self) {
73        let v1 = d1.normalize();
74        if T::abs(v1.x) > T::abs(v1.y) {
75            let v2 = Self::new(-v1.z, T::default(), v1.x).normalize();
76            let v3 = Self::cross(&v1, &v2).normalize();
77            return (v1, v2, v3);
78        } else {
79            let v2 = Self::new(T::default(), v1.z, -v1.y).normalize();
80            let v3 = Self::cross(&v1, &v2).normalize();
81            return (v1, v2, v3);
82        }
83    }
84}
85
86impl<
87        T: Copy
88            + PartialEq
89            + FloatType
90            + std::ops::Add<Output = T>
91            + std::ops::Sub<Output = T>
92            + std::ops::Mul<Output = T>
93            + std::ops::Div<Output = T>
94            + std::ops::MulAssign<T>,
95    > Vector3<T>
96{
97    #[inline]
98    pub fn dot(&self, rhs: &Self) -> T {
99        return self.x * rhs.x + self.y * rhs.y + self.z * rhs.z;
100    }
101
102    #[inline]
103    pub fn length_squared(&self) -> T {
104        return self.dot(self);
105    }
106
107    #[inline]
108    pub fn length(&self) -> T {
109        return FloatType::sqrt(self.x * self.x + self.y * self.y + self.z * self.z);
110    }
111
112    #[inline]
113    pub fn normalize(&self) -> Self {
114        let l = self.length();
115        Vector3::<T> {
116            x: self.x / l,
117            y: self.y / l,
118            z: self.z / l,
119        }
120    }
121
122    #[inline]
123    pub fn distance_squared(a: &Self, b: &Self) -> T {
124        let v = *a - *b;
125        return v.dot(&v);
126    }
127
128    #[inline]
129    pub fn distance(a: &Self, b: &Self) -> T {
130        return FloatType::sqrt(Self::distance_squared(a, b));
131    }
132
133    #[inline]
134    pub fn cross(v1: &Self, v2: &Self) -> Self {
135        //assert!(!v1.has_nans());
136        //assert!(!v2.has_nans());
137        Vector3::<T> {
138            x: (v1.y * v2.z) - (v1.z * v2.y),
139            y: (v1.z * v2.x) - (v1.x * v2.z),
140            z: (v1.x * v2.y) - (v1.y * v2.x),
141        }
142    }
143
144    #[inline]
145    pub fn mul_assign(&mut self, f: T) {
146        self.x *= f;
147        self.y *= f;
148        self.z *= f;
149    }
150}
151
152// Add
153impl<T: std::ops::Add<Output = T>> ops::Add<Vector3<T>> for Vector3<T> {
154    type Output = Vector3<T>;
155    #[inline]
156    fn add(self, rhs: Vector3<T>) -> Vector3<T> {
157        return Vector3 {
158            x: self.x + rhs.x,
159            y: self.y + rhs.y,
160            z: self.z + rhs.z,
161        };
162    }
163}
164
165// Sub
166impl<T: std::ops::Sub<Output = T>> ops::Sub<Vector3<T>> for Vector3<T> {
167    type Output = Vector3<T>;
168    #[inline]
169    fn sub(self, rhs: Vector3<T>) -> Vector3<T> {
170        return Vector3 {
171            x: self.x - rhs.x,
172            y: self.y - rhs.y,
173            z: self.z - rhs.z,
174        };
175    }
176}
177
178// Mul
179// V x V
180impl<T: std::ops::Mul<Output = T>> ops::Mul<Vector3<T>> for Vector3<T> {
181    type Output = Vector3<T>;
182    #[inline]
183    fn mul(self, rhs: Vector3<T>) -> Vector3<T> {
184        return Vector3 {
185            x: self.x * rhs.x,
186            y: self.y * rhs.y,
187            z: self.z * rhs.z,
188        };
189    }
190}
191
192// Mul Scalar
193//V x T
194impl<T: std::ops::Mul<Output = T> + Copy> ops::Mul<T> for Vector3<T> {
195    type Output = Vector3<T>;
196    #[inline]
197    fn mul(self, rhs: T) -> Vector3<T> {
198        return Vector3 {
199            x: self.x * rhs,
200            y: self.y * rhs,
201            z: self.z * rhs,
202        };
203    }
204}
205
206impl<T: std::ops::Div<Output = T> + Copy> ops::Div<T> for Vector3<T> {
207    type Output = Vector3<T>;
208    #[inline]
209    fn div(self, rhs: T) -> Vector3<T> {
210        return Vector3 {
211            x: self.x / rhs,
212            y: self.y / rhs,
213            z: self.z / rhs,
214        };
215    }
216}
217
218impl ops::Mul<Vector3<f32>> for f32 {
219    type Output = Vector3<f32>;
220    #[inline]
221    fn mul(self, rhs: Vector3<f32>) -> Vector3<f32> {
222        return Vector3 {
223            x: self * rhs.x,
224            y: self * rhs.y,
225            z: self * rhs.z,
226        };
227    }
228}
229
230impl ops::Mul<Vector3<f64>> for f64 {
231    type Output = Vector3<f64>;
232    #[inline]
233    fn mul(self, rhs: Vector3<f64>) -> Vector3<f64> {
234        return Vector3 {
235            x: self * rhs.x,
236            y: self * rhs.y,
237            z: self * rhs.z,
238        };
239    }
240}
241
242impl ops::Mul<Vector3<i32>> for i32 {
243    type Output = Vector3<i32>;
244    #[inline]
245    fn mul(self, rhs: Vector3<i32>) -> Vector3<i32> {
246        return Vector3 {
247            x: self * rhs.x,
248            y: self * rhs.y,
249            z: self * rhs.z,
250        };
251    }
252}
253
254impl<T: std::ops::Neg<Output = T>> ops::Neg for Vector3<T> {
255    type Output = Self;
256    #[inline]
257    fn neg(self) -> Self::Output {
258        return Vector3 {
259            x: -self.x,
260            y: -self.y,
261            z: -self.z,
262        };
263    }
264}
265
266impl<T: std::ops::AddAssign<T>> ops::AddAssign for Vector3<T> {
267    #[inline]
268    fn add_assign(&mut self, rhs: Self) {
269        self.x += rhs.x;
270        self.y += rhs.y;
271        self.z += rhs.z;
272    }
273}
274
275impl<T: std::ops::SubAssign<T>> ops::SubAssign for Vector3<T> {
276    #[inline]
277    fn sub_assign(&mut self, rhs: Self) {
278        self.x -= rhs.x;
279        self.y -= rhs.y;
280        self.z -= rhs.z;
281    }
282}
283
284impl<T: std::ops::MulAssign<T>> ops::MulAssign<Vector3<T>> for Vector3<T> {
285    #[inline]
286    fn mul_assign(&mut self, rhs: Self) {
287        self.x *= rhs.x;
288        self.y *= rhs.y;
289        self.z *= rhs.z;
290    }
291}
292
293impl<T: std::ops::MulAssign<T> + Copy> ops::MulAssign<T> for Vector3<T> {
294    #[inline]
295    fn mul_assign(&mut self, rhs: T) {
296        self.x *= rhs;
297        self.y *= rhs;
298        self.z *= rhs;
299    }
300}
301
302impl<T: std::ops::DivAssign<T>> ops::DivAssign<Vector3<T>> for Vector3<T> {
303    #[inline]
304    fn div_assign(&mut self, rhs: Self) {
305        self.x /= rhs.x;
306        self.y /= rhs.y;
307        self.z /= rhs.z;
308    }
309}
310
311impl<T: std::ops::DivAssign<T> + Copy> ops::DivAssign<T> for Vector3<T> {
312    #[inline]
313    fn div_assign(&mut self, rhs: T) {
314        self.x /= rhs;
315        self.y /= rhs;
316        self.z /= rhs;
317    }
318}
319
320impl<T> ops::Index<usize> for Vector3<T> {
321    type Output = T;
322    #[inline]
323    fn index(&self, i: usize) -> &Self::Output {
324        match i {
325            0 => &self.x,
326            1 => &self.y,
327            _ => &self.z,
328        }
329    }
330}
331
332impl<T> ops::IndexMut<usize> for Vector3<T> {
333    #[inline]
334    fn index_mut(&mut self, i: usize) -> &mut Self::Output {
335        match i {
336            0 => &mut self.x,
337            1 => &mut self.y,
338            _ => &mut self.z,
339        }
340    }
341}
342
343impl<T: Copy> From<T> for Vector3<T> {
344    #[inline]
345    fn from(value: T) -> Self {
346        Vector3::<T>::new(value, value, value)
347    }
348}
349
350impl<T: Copy> From<(T, T, T)> for Vector3<T> {
351    #[inline]
352    fn from(value: (T, T, T)) -> Self {
353        Vector3::<T>::new(value.0, value.1, value.2)
354    }
355}
356
357impl<T: Copy> From<[T; 3]> for Vector3<T> {
358    #[inline]
359    fn from(value: [T; 3]) -> Self {
360        Vector3::<T>::new(value[0], value[1], value[2])
361    }
362}
363
364impl<T: Copy> From<&[T]> for Vector3<T> {
365    #[inline]
366    fn from(value: &[T]) -> Self {
367        Vector3::<T>::new(value[0], value[1], value[2])
368    }
369}
370
371//------------------
372#[cfg(test)]
373mod tests {
374    use super::*;
375
376    type Vector3f = Vector3<f32>;
377    type Vector3d = Vector3<f64>;
378    type Vector3i = Vector3<i32>;
379
380    #[test]
381    fn test_001() {
382        let v1 = Vector3f::new(1.0, 2.0, 3.0);
383        let v2 = Vector3f::new(4.0, 5.0, 6.0);
384        let v3 = v1 + v2;
385        let v4 = Vector3f::new(5.0, 7.0, 9.0);
386        assert_eq!(v3, v4);
387    }
388
389    #[test]
390    fn test_002() {
391        let v1 = Vector3f::new(1.0, 2.0, 3.0);
392        let v2 = Vector3f::new(4.0, 5.0, 6.0);
393        let v3 = v2 - v1;
394        let v4 = Vector3f::new(3.0, 3.0, 3.0);
395        assert_eq!(v3, v4);
396    }
397
398    #[test]
399    fn test_003_f1() {
400        let v1 = Vector3f::new(1.0, 2.0, 3.0);
401        let v2 = Vector3f::new(4.0, 5.0, 6.0);
402        let v3 = v2 * v1;
403        let v4 = Vector3f::new(4.0, 10.0, 18.0);
404        assert_eq!(v3, v4);
405    }
406
407    #[test]
408    fn test_003_f2() {
409        let v1 = 2.0;
410        let v2 = Vector3f::new(4.0, 5.0, 6.0);
411        let v3 = v1 * v2;
412        let v4 = Vector3f::new(8.0, 10.0, 12.0);
413        assert_eq!(v3, v4);
414    }
415
416    #[test]
417    fn test_003_d1() {
418        let v1 = Vector3d::new(1.0, 2.0, 3.0);
419        let v2 = Vector3d::new(4.0, 5.0, 6.0);
420        let v3 = v2 * v1;
421        let v4 = Vector3d::new(4.0, 10.0, 18.0);
422        assert_eq!(v3, v4);
423    }
424
425    #[test]
426    fn test_003_d2() {
427        let v1 = 2.0;
428        let v2 = Vector3d::new(4.0, 5.0, 6.0);
429        let v3 = v1 * v2;
430        let v4 = Vector3d::new(8.0, 10.0, 12.0);
431        assert_eq!(v3, v4);
432    }
433
434    #[test]
435    fn test_003_i1() {
436        let v1 = Vector3i::new(1, 2, 3);
437        let v2 = Vector3i::new(4, 5, 6);
438        let v3 = v2 * v1;
439        let v4 = Vector3i::new(4, 10, 18);
440        assert_eq!(v3, v4);
441    }
442
443    #[test]
444    fn test_003_i2() {
445        let v1 = 2;
446        let v2 = Vector3i::new(4, 5, 6);
447        let v3 = v1 * v2;
448        let v4 = Vector3i::new(8, 10, 12);
449        assert_eq!(v3, v4);
450    }
451
452    #[test]
453    fn test_004() {
454        let v1 = Vector3f::new(-1.0, 2.0, -3.0);
455        let v3 = v1.abs();
456        let v4 = Vector3f::new(1.0, 2.0, 3.0);
457        assert_eq!(v3, v4);
458    }
459
460    #[test]
461    fn test_005() {
462        let v1 = Vector3d::new(-1.0, 2.0, -3.0);
463        let v3 = v1.abs();
464        let v4 = Vector3d::new(1.0, 2.0, 3.0);
465        assert_eq!(v3, v4);
466    }
467
468    #[test]
469    fn test_006() {
470        let v1 = Vector3i::new(-1, 2, -3);
471        let v3 = v1.abs();
472        let v4 = Vector3i::new(1, 2, 3);
473        assert_eq!(v3, v4);
474    }
475
476    #[test]
477    fn test_007() {
478        let v1 = Vector3f::new(4.0, 0.0, 0.0);
479        let l1 = v1.length();
480        let l2 = 4.0;
481        assert_eq!(l1, l2);
482    }
483
484    #[test]
485    fn test_008() {
486        let v1 = Vector3f::new(4.0, 0.0, 0.0);
487        let l1 = v1.length_squared();
488        let l2 = 16.0;
489        assert_eq!(l1, l2);
490    }
491
492    #[test]
493    fn test_009() {
494        let v1 = Vector3f::new(4.0, 0.0, 0.0);
495        let v2 = v1.normalize();
496        let v3 = Vector3f::new(1.0, 0.0, 0.0);
497        assert_eq!(v2, v3);
498    }
499
500    #[test]
501    fn test_010() {
502        let v1 = Vector3f::new(1.0, 2.0, 3.0);
503        let v2 = Vector3f::from((1.0, 2.0, 3.0));
504        let v3 = Vector3f::from([1.0, 2.0, 3.0]);
505        assert_eq!(v1, v2);
506        assert_eq!(v1, v3);
507    }
508}