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 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
152impl<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
165impl<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
178impl<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
192impl<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#[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}