1use core::iter::Sum;
2use core::ops::{
3 Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub, SubAssign,
4};
5
6use crate::Scalar;
7
8pub struct Vector3<T> {
10 pub x: T,
12 pub y: T,
14 pub z: T,
16}
17
18impl<T: ::core::marker::Copy> ::core::marker::Copy for Vector3<T> {}
19
20impl<T: ::core::clone::Clone> ::core::clone::Clone for Vector3<T> {
21 #[inline]
22 fn clone(&self) -> Self {
23 Self {
24 x: self.x.clone(),
25 y: self.y.clone(),
26 z: self.z.clone(),
27 }
28 }
29}
30
31impl<T: ::core::fmt::Debug> ::core::fmt::Debug for Vector3<T> {
32 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
33 f.debug_struct("Vector3")
34 .field("x", &self.x)
35 .field("y", &self.y)
36 .field("z", &self.z)
37 .finish()
38 }
39}
40
41impl<T: ::core::cmp::PartialEq> ::core::cmp::PartialEq for Vector3<T> {
42 #[inline]
43 fn eq(&self, other: &Self) -> bool {
44 self.x == other.x && self.y == other.y && self.z == other.z
45 }
46}
47
48impl<T> Vector3<T> {
49 #[inline]
51 pub const fn new(x: T, y: T, z: T) -> Self {
52 Self { x, y, z }
53 }
54
55 #[inline]
57 pub fn from_array(array: [T; 3]) -> Self {
58 let [x, y, z] = array;
59 Self { x, y, z }
60 }
61
62 #[inline]
64 pub fn to_array(self) -> [T; 3] {
65 [self.x, self.y, self.z]
66 }
67
68 #[inline]
70 pub fn with_x(self, x: T) -> Self {
71 Self {
72 x,
73 y: self.y,
74 z: self.z,
75 }
76 }
77
78 #[inline]
80 pub fn with_y(self, y: T) -> Self {
81 Self {
82 x: self.x,
83 y,
84 z: self.z,
85 }
86 }
87
88 #[inline]
90 pub fn with_z(self, z: T) -> Self {
91 Self {
92 x: self.x,
93 y: self.y,
94 z,
95 }
96 }
97
98 #[inline]
100 pub fn map<U, F: FnMut(T) -> U>(self, mut f: F) -> Vector3<U> {
101 Vector3 {
102 x: f(self.x),
103 y: f(self.y),
104 z: f(self.z),
105 }
106 }
107
108 #[inline]
110 pub fn zip_map<U, R, F: FnMut(T, U) -> R>(self, rhs: Vector3<U>, mut f: F) -> Vector3<R> {
111 Vector3 {
112 x: f(self.x, rhs.x),
113 y: f(self.y, rhs.y),
114 z: f(self.z, rhs.z),
115 }
116 }
117}
118
119impl<T: Copy> Vector3<T> {
120 #[inline]
122 pub const fn splat(value: T) -> Self {
123 Self {
124 x: value,
125 y: value,
126 z: value,
127 }
128 }
129
130 #[inline]
136 pub fn from_slice(slice: &[T]) -> Self {
137 Self {
138 x: slice[0],
139 y: slice[1],
140 z: slice[2],
141 }
142 }
143}
144
145impl<T> Index<usize> for Vector3<T> {
146 type Output = T;
147
148 #[inline]
155 fn index(&self, index: usize) -> &T {
156 match index {
157 0 => &self.x,
158 1 => &self.y,
159 2 => &self.z,
160 _ => panic!("index out of bounds: Vector3 has 3 components but the index is {index}"),
161 }
162 }
163}
164
165impl<T> IndexMut<usize> for Vector3<T> {
166 #[inline]
173 fn index_mut(&mut self, index: usize) -> &mut T {
174 match index {
175 0 => &mut self.x,
176 1 => &mut self.y,
177 2 => &mut self.z,
178 _ => panic!("index out of bounds: Vector3 has 3 components but the index is {index}"),
179 }
180 }
181}
182
183impl<T: Default> Default for Vector3<T> {
184 #[inline]
186 fn default() -> Self {
187 Self {
188 x: T::default(),
189 y: T::default(),
190 z: T::default(),
191 }
192 }
193}
194
195impl<T: Neg<Output = T>> Neg for Vector3<T> {
196 type Output = Self;
197 #[inline]
199 fn neg(self) -> Self {
200 Self::new(-self.x, -self.y, -self.z)
201 }
202}
203
204impl<T: Add<Output = T>> Add for Vector3<T> {
205 type Output = Self;
206 #[inline]
208 fn add(self, rhs: Self) -> Self {
209 Self::new(self.x + rhs.x, self.y + rhs.y, self.z + rhs.z)
210 }
211}
212
213impl<T: AddAssign> AddAssign for Vector3<T> {
214 #[inline]
215 fn add_assign(&mut self, rhs: Self) {
216 self.x += rhs.x;
217 self.y += rhs.y;
218 self.z += rhs.z;
219 }
220}
221
222impl<T: Sub<Output = T>> Sub for Vector3<T> {
223 type Output = Self;
224 #[inline]
226 fn sub(self, rhs: Self) -> Self {
227 Self::new(self.x - rhs.x, self.y - rhs.y, self.z - rhs.z)
228 }
229}
230
231impl<T: SubAssign> SubAssign for Vector3<T> {
232 #[inline]
233 fn sub_assign(&mut self, rhs: Self) {
234 self.x -= rhs.x;
235 self.y -= rhs.y;
236 self.z -= rhs.z;
237 }
238}
239
240impl<T, S: Scalar> Mul<S> for Vector3<T>
241where
242 T: Mul<S, Output = T>,
243{
244 type Output = Self;
245 #[inline]
247 fn mul(self, rhs: S) -> Self {
248 Self::new(self.x * rhs, self.y * rhs, self.z * rhs)
249 }
250}
251
252impl<T, S: Scalar> MulAssign<S> for Vector3<T>
253where
254 T: MulAssign<S>,
255{
256 #[inline]
257 fn mul_assign(&mut self, rhs: S) {
258 self.x *= rhs;
259 self.y *= rhs;
260 self.z *= rhs;
261 }
262}
263
264impl<T, S: Scalar> Div<S> for Vector3<T>
265where
266 T: Div<S, Output = T>,
267{
268 type Output = Self;
269 #[inline]
271 fn div(self, rhs: S) -> Self {
272 Self::new(self.x / rhs, self.y / rhs, self.z / rhs)
273 }
274}
275
276impl<T, S: Scalar> DivAssign<S> for Vector3<T>
277where
278 T: DivAssign<S>,
279{
280 #[inline]
281 fn div_assign(&mut self, rhs: S) {
282 self.x /= rhs;
283 self.y /= rhs;
284 self.z /= rhs;
285 }
286}
287
288impl<T: Add<Output = T> + Default + Copy> Sum for Vector3<T> {
289 #[inline]
290 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
291 iter.fold(Self::default(), |acc, v| acc + v)
292 }
293}
294
295impl<'a, T: Add<Output = T> + Default + Copy> Sum<&'a Vector3<T>> for Vector3<T> {
296 #[inline]
297 fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
298 iter.copied().fold(Self::default(), |acc, v| acc + v)
299 }
300}
301
302impl<T: Add<Output = T>> Vector3<T> {
303 #[inline]
305 pub fn element_sum(self) -> T {
306 self.x + self.y + self.z
307 }
308}
309
310impl<T: Add<Output = T> + Sub<Output = T> + Copy> Vector3<T> {
311 #[inline]
315 pub fn lerp<S: Scalar>(self, rhs: Self, t: S) -> Self
316 where
317 T: Mul<S, Output = T>,
318 {
319 self + (rhs - self) * t
320 }
321}
322
323impl<V: Scalar> Vector3<V> {
324 pub const ZERO: Self = Self::new(V::ZERO, V::ZERO, V::ZERO);
326
327 pub const ONE: Self = Self::new(V::ONE, V::ONE, V::ONE);
329
330 pub const X: Self = Self::new(V::ONE, V::ZERO, V::ZERO);
332
333 pub const Y: Self = Self::new(V::ZERO, V::ONE, V::ZERO);
335
336 pub const Z: Self = Self::new(V::ZERO, V::ZERO, V::ONE);
338
339 #[inline]
341 pub fn dot(self, rhs: Self) -> V {
342 self.x * rhs.x + self.y * rhs.y + self.z * rhs.z
343 }
344
345 #[inline]
347 pub fn cross(self, rhs: Self) -> Self {
348 Self::new(
349 self.y * rhs.z - self.z * rhs.y,
350 self.z * rhs.x - self.x * rhs.z,
351 self.x * rhs.y - self.y * rhs.x,
352 )
353 }
354
355 #[inline]
360 pub fn norm_squared(self) -> V {
361 self.dot(self)
362 }
363
364 #[inline]
366 pub fn norm(self) -> V {
367 self.norm_squared().sqrt()
368 }
369
370 #[inline]
376 pub fn normalize(self) -> Self {
377 self / self.norm()
378 }
379
380 #[inline]
383 pub fn try_normalize(self) -> Option<Self> {
384 let norm = self.norm();
385 if norm.is_finite() && norm > V::ZERO {
386 Some(self / norm)
387 } else {
388 None
389 }
390 }
391
392 #[inline]
395 pub fn normalize_or_zero(self) -> Self {
396 self.try_normalize().unwrap_or(Self::ZERO)
397 }
398
399 #[inline]
402 pub fn is_normalized(self) -> bool {
403 (self.norm_squared() - V::ONE).abs() <= V::from_f64(2.0e-4)
404 }
405
406 #[inline]
412 pub fn angle_between(self, rhs: Self) -> V {
413 self.cross(rhs).norm().atan2(self.dot(rhs))
414 }
415
416 #[inline]
418 pub fn project_onto(self, onto: Self) -> Self {
419 onto * (self.dot(onto) / onto.norm_squared())
420 }
421
422 #[inline]
424 pub fn reject_from(self, from: Self) -> Self {
425 self - self.project_onto(from)
426 }
427
428 #[inline]
431 pub fn reflect(self, normal: Self) -> Self {
432 self - normal * (self.dot(normal) * (V::ONE + V::ONE))
433 }
434
435 #[inline]
437 pub fn recip(self) -> Self {
438 Self::new(self.x.recip(), self.y.recip(), self.z.recip())
439 }
440
441 #[inline]
443 pub fn element_product(self) -> V {
444 self.x * self.y * self.z
445 }
446
447 #[inline]
449 pub fn abs(self) -> Self {
450 Self::new(self.x.abs(), self.y.abs(), self.z.abs())
451 }
452
453 #[inline]
455 pub fn min(self, rhs: Self) -> Self {
456 Self::new(self.x.min(rhs.x), self.y.min(rhs.y), self.z.min(rhs.z))
457 }
458
459 #[inline]
461 pub fn max(self, rhs: Self) -> Self {
462 Self::new(self.x.max(rhs.x), self.y.max(rhs.y), self.z.max(rhs.z))
463 }
464
465 #[inline]
472 pub fn clamp(self, min: Self, max: Self) -> Self {
473 Self::new(
474 self.x.clamp(min.x, max.x),
475 self.y.clamp(min.y, max.y),
476 self.z.clamp(min.z, max.z),
477 )
478 }
479
480 #[inline]
482 pub fn min_element(self) -> V {
483 self.x.min(self.y).min(self.z)
484 }
485
486 #[inline]
488 pub fn max_element(self) -> V {
489 self.x.max(self.y).max(self.z)
490 }
491
492 #[inline]
494 pub fn floor(self) -> Self {
495 Self::new(self.x.floor(), self.y.floor(), self.z.floor())
496 }
497
498 #[inline]
500 pub fn ceil(self) -> Self {
501 Self::new(self.x.ceil(), self.y.ceil(), self.z.ceil())
502 }
503
504 #[inline]
507 pub fn round(self) -> Self {
508 Self::new(self.x.round(), self.y.round(), self.z.round())
509 }
510
511 #[inline]
513 pub fn round_ties_even(self) -> Self {
514 Self::new(
515 self.x.round_ties_even(),
516 self.y.round_ties_even(),
517 self.z.round_ties_even(),
518 )
519 }
520
521 #[inline]
523 pub fn trunc(self) -> Self {
524 Self::new(self.x.trunc(), self.y.trunc(), self.z.trunc())
525 }
526
527 #[inline]
529 pub fn fract(self) -> Self {
530 Self::new(self.x.fract(), self.y.fract(), self.z.fract())
531 }
532
533 #[inline]
536 pub fn copysign(self, sign: Self) -> Self {
537 Self::new(
538 self.x.copysign(sign.x),
539 self.y.copysign(sign.y),
540 self.z.copysign(sign.z),
541 )
542 }
543
544 #[inline]
546 pub fn signum(self) -> Self {
547 Self::new(self.x.signum(), self.y.signum(), self.z.signum())
548 }
549
550 #[inline]
552 pub fn rem_euclid(self, rhs: Self) -> Self {
553 Self::new(
554 self.x.rem_euclid(rhs.x),
555 self.y.rem_euclid(rhs.y),
556 self.z.rem_euclid(rhs.z),
557 )
558 }
559
560 #[inline]
562 pub fn is_finite(self) -> bool {
563 self.x.is_finite() && self.y.is_finite() && self.z.is_finite()
564 }
565
566 #[inline]
568 pub fn is_infinite(self) -> bool {
569 self.x.is_infinite() || self.y.is_infinite() || self.z.is_infinite()
570 }
571
572 #[inline]
574 pub fn is_nan(self) -> bool {
575 self.x.is_nan() || self.y.is_nan() || self.z.is_nan()
576 }
577}
578
579#[cfg(test)]
580mod tests {
581 use super::*;
582 use core::f64::consts::FRAC_PI_2;
583 use core::iter;
584
585 #[test]
586 fn new() {
587 let v = Vector3::new(1.0, 2.0, 3.0);
588 assert_eq!((v.x, v.y, v.z), (1.0, 2.0, 3.0));
589 }
590
591 #[test]
592 fn from_array() {
593 assert_eq!(
594 Vector3::from_array([1.0, 2.0, 3.0]),
595 Vector3::new(1.0, 2.0, 3.0)
596 );
597 }
598
599 #[test]
600 fn to_array() {
601 assert_eq!(Vector3::new(1.0, 2.0, 3.0).to_array(), [1.0, 2.0, 3.0]);
602 }
603
604 #[test]
605 fn splat() {
606 assert_eq!(Vector3::splat(5.0), Vector3::new(5.0, 5.0, 5.0));
607 }
608
609 #[test]
610 fn from_slice() {
611 assert_eq!(
612 Vector3::from_slice(&[1.0, 2.0, 3.0, 4.0]),
613 Vector3::new(1.0, 2.0, 3.0)
614 );
615 }
616
617 #[test]
618 #[should_panic]
619 fn from_slice_panics_when_too_short() {
620 Vector3::<f64>::from_slice(&[1.0, 2.0]);
621 }
622
623 #[test]
624 fn with_x() {
625 assert_eq!(
626 Vector3::new(1.0, 2.0, 3.0).with_x(9.0),
627 Vector3::new(9.0, 2.0, 3.0)
628 );
629 }
630
631 #[test]
632 fn with_y() {
633 assert_eq!(
634 Vector3::new(1.0, 2.0, 3.0).with_y(9.0),
635 Vector3::new(1.0, 9.0, 3.0)
636 );
637 }
638
639 #[test]
640 fn with_z() {
641 assert_eq!(
642 Vector3::new(1.0, 2.0, 3.0).with_z(9.0),
643 Vector3::new(1.0, 2.0, 9.0)
644 );
645 }
646
647 #[test]
648 fn map() {
649 assert_eq!(
650 Vector3::new(1.0, 2.0, 3.0).map(|c| c * 2.0),
651 Vector3::new(2.0, 4.0, 6.0)
652 );
653 }
654
655 #[test]
656 fn zip_map() {
657 assert_eq!(
658 Vector3::new(1.0, 2.0, 3.0).zip_map(Vector3::new(4.0, 5.0, 6.0), |a, b| a + b),
659 Vector3::new(5.0, 7.0, 9.0)
660 );
661 }
662
663 #[test]
664 fn default_is_zero() {
665 assert_eq!(Vector3::<f64>::default(), Vector3::new(0.0, 0.0, 0.0));
666 }
667
668 #[test]
669 fn copy_and_clone() {
670 let a = Vector3::new(1.0, 2.0, 3.0);
671 let b = a;
672 let c = ::core::clone::Clone::clone(&a);
673 assert_eq!(a, b);
674 assert_eq!(a, c);
675 }
676
677 #[test]
678 fn eq() {
679 let a = Vector3::new(1.0, 2.0, 3.0);
680 assert_eq!(a, Vector3::new(1.0, 2.0, 3.0));
681 assert_ne!(a, Vector3::new(1.0, 2.0, 4.0));
682 }
683
684 #[test]
685 fn debug() {
686 assert_eq!(
687 format!("{:?}", Vector3::new(1.0, 2.0, 3.0)),
688 "Vector3 { x: 1.0, y: 2.0, z: 3.0 }"
689 );
690 }
691
692 #[test]
693 fn index() {
694 let v = Vector3::new(1.0, 2.0, 3.0);
695 assert_eq!((v[0], v[1], v[2]), (1.0, 2.0, 3.0));
696 }
697
698 #[test]
699 fn index_mut() {
700 let mut v = Vector3::new(1.0, 2.0, 3.0);
701 v[1] = 9.0;
702 assert_eq!(v.y, 9.0);
703 }
704
705 #[test]
706 #[should_panic]
707 fn index_panics_when_out_of_bounds() {
708 let _ = Vector3::new(1.0, 2.0, 3.0)[3];
709 }
710
711 #[test]
712 #[should_panic]
713 fn index_mut_panics_when_out_of_bounds() {
714 Vector3::new(1.0, 2.0, 3.0)[3] = 0.0;
715 }
716
717 #[test]
718 fn constants() {
719 assert_eq!(Vector3::<f64>::ZERO, Vector3::new(0.0, 0.0, 0.0));
720 assert_eq!(Vector3::<f64>::ONE, Vector3::new(1.0, 1.0, 1.0));
721 assert_eq!(Vector3::<f64>::X, Vector3::new(1.0, 0.0, 0.0));
722 assert_eq!(Vector3::<f64>::Y, Vector3::new(0.0, 1.0, 0.0));
723 assert_eq!(Vector3::<f64>::Z, Vector3::new(0.0, 0.0, 1.0));
724 }
725
726 #[test]
727 fn neg() {
728 assert_eq!(-Vector3::new(1.0, -2.0, 3.0), Vector3::new(-1.0, 2.0, -3.0));
729 }
730
731 #[test]
732 fn add() {
733 assert_eq!(
734 Vector3::new(1.0, 2.0, 3.0) + Vector3::new(4.0, 5.0, 6.0),
735 Vector3::new(5.0, 7.0, 9.0)
736 );
737 }
738
739 #[test]
740 fn add_assign() {
741 let mut v = Vector3::new(1.0, 2.0, 3.0);
742 v += Vector3::new(4.0, 5.0, 6.0);
743 assert_eq!(v, Vector3::new(5.0, 7.0, 9.0));
744 }
745
746 #[test]
747 fn sub() {
748 assert_eq!(
749 Vector3::new(4.0, 5.0, 6.0) - Vector3::new(1.0, 2.0, 3.0),
750 Vector3::new(3.0, 3.0, 3.0)
751 );
752 }
753
754 #[test]
755 fn sub_assign() {
756 let mut v = Vector3::new(4.0, 5.0, 6.0);
757 v -= Vector3::new(1.0, 2.0, 3.0);
758 assert_eq!(v, Vector3::new(3.0, 3.0, 3.0));
759 }
760
761 #[test]
762 fn mul_scalar() {
763 assert_eq!(
764 Vector3::new(1.0, 2.0, 3.0) * 2.0,
765 Vector3::new(2.0, 4.0, 6.0)
766 );
767 }
768
769 #[test]
770 fn mul_assign_scalar() {
771 let mut v = Vector3::new(1.0, 2.0, 3.0);
772 v *= 2.0;
773 assert_eq!(v, Vector3::new(2.0, 4.0, 6.0));
774 }
775
776 #[test]
777 fn div_scalar() {
778 assert_eq!(
779 Vector3::new(2.0, 4.0, 6.0) / 2.0,
780 Vector3::new(1.0, 2.0, 3.0)
781 );
782 }
783
784 #[test]
785 fn div_assign_scalar() {
786 let mut v = Vector3::new(2.0, 4.0, 6.0);
787 v /= 2.0;
788 assert_eq!(v, Vector3::new(1.0, 2.0, 3.0));
789 }
790
791 #[test]
792 fn sum_owned() {
793 let v = [
794 Vector3::new(1.0, 1.0, 1.0),
795 Vector3::new(2.0, 2.0, 2.0),
796 Vector3::new(3.0, 3.0, 3.0),
797 ];
798 let total: Vector3<f64> = v.iter().copied().sum();
799 assert_eq!(total, Vector3::new(6.0, 6.0, 6.0));
800 }
801
802 #[test]
803 fn sum_borrowed() {
804 let v = [
805 Vector3::new(1.0, 1.0, 1.0),
806 Vector3::new(2.0, 2.0, 2.0),
807 Vector3::new(3.0, 3.0, 3.0),
808 ];
809 let total: Vector3<f64> = v.iter().sum();
810 assert_eq!(total, Vector3::new(6.0, 6.0, 6.0));
811 }
812
813 #[test]
814 fn sum_empty() {
815 let total: Vector3<f64> = iter::empty::<Vector3<f64>>().sum();
816 assert_eq!(total, Vector3::new(0.0, 0.0, 0.0));
817 }
818
819 #[test]
820 fn element_sum() {
821 assert_eq!(Vector3::new(1.0, 2.0, 3.0).element_sum(), 6.0);
822 }
823
824 #[test]
825 fn element_product() {
826 assert_eq!(Vector3::new(2.0, 3.0, 4.0).element_product(), 24.0);
827 }
828
829 #[test]
830 fn lerp() {
831 assert_eq!(
832 Vector3::new(0.0, 0.0, 0.0).lerp(Vector3::new(2.0, 4.0, 6.0), 0.5),
833 Vector3::new(1.0, 2.0, 3.0)
834 );
835 }
836
837 #[test]
838 fn dot() {
839 assert_eq!(
840 Vector3::new(1.0, 2.0, 3.0).dot(Vector3::new(4.0, 5.0, 6.0)),
841 32.0
842 );
843 }
844
845 #[test]
846 fn cross() {
847 assert_eq!(Vector3::<f64>::X.cross(Vector3::Y), Vector3::Z);
848 assert_eq!(
849 Vector3::new(1.0, 2.0, 3.0).cross(Vector3::new(4.0, 5.0, 6.0)),
850 Vector3::new(-3.0, 6.0, -3.0)
851 );
852 }
853
854 #[test]
855 fn norm_squared() {
856 assert_eq!(Vector3::new(1.0, 2.0, 2.0).norm_squared(), 9.0);
857 }
858
859 #[test]
860 fn norm() {
861 assert_eq!(Vector3::new(3.0, 4.0, 0.0).norm(), 5.0);
862 }
863
864 #[test]
865 fn normalize() {
866 let n = Vector3::new(3.0, 4.0, 0.0).normalize();
867 assert!((n - Vector3::new(0.6, 0.8, 0.0)).norm() < 1e-12);
868 }
869
870 #[test]
871 fn try_normalize() {
872 let n = Vector3::new(3.0, 4.0, 0.0).try_normalize().unwrap();
873 assert!((n - Vector3::new(0.6, 0.8, 0.0)).norm() < 1e-12);
874 }
875
876 #[test]
877 fn try_normalize_zero_is_none() {
878 assert_eq!(Vector3::<f64>::ZERO.try_normalize(), None);
879 }
880
881 #[test]
882 fn normalize_or_zero() {
883 let n = Vector3::new(3.0, 4.0, 0.0).normalize_or_zero();
884 assert!((n - Vector3::new(0.6, 0.8, 0.0)).norm() < 1e-12);
885 }
886
887 #[test]
888 fn normalize_or_zero_zero_is_zero() {
889 assert_eq!(Vector3::<f64>::ZERO.normalize_or_zero(), Vector3::ZERO);
890 }
891
892 #[test]
893 fn is_normalized() {
894 assert!(Vector3::<f64>::X.is_normalized());
895 assert!(!Vector3::new(2.0, 0.0, 0.0).is_normalized());
896 }
897
898 #[test]
899 fn angle_between() {
900 assert!((Vector3::<f64>::X.angle_between(Vector3::Y) - FRAC_PI_2).abs() < 1e-12);
901 assert!(Vector3::<f64>::X.angle_between(Vector3::X).abs() < 1e-12);
902 }
903
904 #[test]
905 fn project_onto() {
906 assert_eq!(
907 Vector3::new(2.0, 3.0, 0.0).project_onto(Vector3::X),
908 Vector3::new(2.0, 0.0, 0.0)
909 );
910 }
911
912 #[test]
913 fn reject_from() {
914 assert_eq!(
915 Vector3::new(2.0, 3.0, 0.0).reject_from(Vector3::X),
916 Vector3::new(0.0, 3.0, 0.0)
917 );
918 }
919
920 #[test]
921 fn reflect() {
922 assert_eq!(
923 Vector3::new(1.0, -1.0, 0.0).reflect(Vector3::Y),
924 Vector3::new(1.0, 1.0, 0.0)
925 );
926 }
927
928 #[test]
929 fn recip() {
930 assert_eq!(
931 Vector3::new(2.0, 4.0, 8.0).recip(),
932 Vector3::new(0.5, 0.25, 0.125)
933 );
934 }
935
936 #[test]
937 fn abs() {
938 assert_eq!(
939 Vector3::new(-1.0, 2.0, -3.0).abs(),
940 Vector3::new(1.0, 2.0, 3.0)
941 );
942 }
943
944 #[test]
945 fn min() {
946 assert_eq!(
947 Vector3::new(1.0, 5.0, 3.0).min(Vector3::new(4.0, 2.0, 6.0)),
948 Vector3::new(1.0, 2.0, 3.0)
949 );
950 }
951
952 #[test]
953 fn max() {
954 assert_eq!(
955 Vector3::new(1.0, 5.0, 3.0).max(Vector3::new(4.0, 2.0, 6.0)),
956 Vector3::new(4.0, 5.0, 6.0)
957 );
958 }
959
960 #[test]
961 fn clamp() {
962 assert_eq!(
963 Vector3::new(5.0, -1.0, 2.0).clamp(Vector3::splat(0.0), Vector3::splat(3.0)),
964 Vector3::new(3.0, 0.0, 2.0)
965 );
966 }
967
968 #[test]
969 #[should_panic]
970 fn clamp_panics_when_min_gt_max() {
971 Vector3::new(1.0, 1.0, 1.0).clamp(Vector3::splat(3.0), Vector3::splat(0.0));
972 }
973
974 #[test]
975 fn min_element() {
976 assert_eq!(Vector3::new(3.0, 1.0, 2.0).min_element(), 1.0);
977 }
978
979 #[test]
980 fn max_element() {
981 assert_eq!(Vector3::new(3.0, 1.0, 2.0).max_element(), 3.0);
982 }
983
984 #[test]
985 fn floor() {
986 assert_eq!(
987 Vector3::new(1.7, -1.2, 2.0).floor(),
988 Vector3::new(1.0, -2.0, 2.0)
989 );
990 }
991
992 #[test]
993 fn ceil() {
994 assert_eq!(
995 Vector3::new(1.2, -1.7, 2.0).ceil(),
996 Vector3::new(2.0, -1.0, 2.0)
997 );
998 }
999
1000 #[test]
1001 fn round() {
1002 assert_eq!(
1003 Vector3::new(1.5, -1.5, 2.4).round(),
1004 Vector3::new(2.0, -2.0, 2.0)
1005 );
1006 }
1007
1008 #[test]
1009 fn round_ties_even() {
1010 assert_eq!(
1011 Vector3::new(1.5, 2.5, -1.5).round_ties_even(),
1012 Vector3::new(2.0, 2.0, -2.0)
1013 );
1014 }
1015
1016 #[test]
1017 fn trunc() {
1018 assert_eq!(
1019 Vector3::new(1.7, -1.7, 2.0).trunc(),
1020 Vector3::new(1.0, -1.0, 2.0)
1021 );
1022 }
1023
1024 #[test]
1025 fn fract() {
1026 assert_eq!(
1027 Vector3::new(2.5, -1.25, 0.0).fract(),
1028 Vector3::new(0.5, -0.25, 0.0)
1029 );
1030 }
1031
1032 #[test]
1033 fn copysign() {
1034 assert_eq!(
1035 Vector3::new(3.0, -4.0, 5.0).copysign(Vector3::new(-1.0, 1.0, -1.0)),
1036 Vector3::new(-3.0, 4.0, -5.0)
1037 );
1038 }
1039
1040 #[test]
1041 fn signum() {
1042 assert_eq!(
1043 Vector3::new(3.0, -2.0, 5.0).signum(),
1044 Vector3::new(1.0, -1.0, 1.0)
1045 );
1046 }
1047
1048 #[test]
1049 fn rem_euclid() {
1050 assert_eq!(
1051 Vector3::new(-7.0, 7.0, 8.0).rem_euclid(Vector3::splat(3.0)),
1052 Vector3::new(2.0, 1.0, 2.0)
1053 );
1054 }
1055
1056 #[test]
1057 fn is_finite() {
1058 assert!(Vector3::new(1.0, 2.0, 3.0).is_finite());
1059 assert!(!Vector3::new(1.0, f64::INFINITY, 3.0).is_finite());
1060 }
1061
1062 #[test]
1063 fn is_infinite() {
1064 assert!(Vector3::new(1.0, f64::INFINITY, 3.0).is_infinite());
1065 assert!(!Vector3::new(1.0, 2.0, 3.0).is_infinite());
1066 }
1067
1068 #[test]
1069 fn is_nan() {
1070 assert!(Vector3::new(1.0, f64::NAN, 3.0).is_nan());
1071 assert!(!Vector3::new(1.0, 2.0, 3.0).is_nan());
1072 }
1073
1074 #[test]
1075 fn f32_normalize() {
1076 let n = Vector3::<f32>::new(3.0, 4.0, 0.0).normalize();
1077 assert!((n - Vector3::new(0.6, 0.8, 0.0)).norm() < 1e-6);
1078 }
1079}