pbrt_r3/core/geometry/
vector2.rs

1use 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
106// Add
107impl<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
118// Sub
119impl<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
130// Mul
131// V x V
132impl<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
143// Mul Scalar
144//V x T
145impl<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//--------------------------
309#[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}