1use super::UnknownUnit;
11use crate::approxeq::ApproxEq;
12use crate::approxord::{max, min};
13use crate::length::Length;
14use crate::num::*;
15use crate::point::{point2, point3, Point2D, Point3D};
16use crate::scale::Scale;
17use crate::size::{size2, size3, Size2D, Size3D};
18use crate::transform2d::Transform2D;
19use crate::transform3d::Transform3D;
20use crate::trig::Trig;
21use crate::Angle;
22use core::cmp::{Eq, PartialEq};
23use core::fmt;
24use core::hash::Hash;
25use core::iter::Sum;
26use core::marker::PhantomData;
27use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
28#[cfg(feature = "malloc_size_of")]
29use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
30#[cfg(feature = "mint")]
31use mint;
32use num_traits::real::Real;
33use num_traits::{Float, NumCast, Signed};
34#[cfg(feature = "serde")]
35use serde;
36
37#[cfg(feature = "bytemuck")]
38use bytemuck::{Pod, Zeroable};
39
40#[repr(C)]
42pub struct Vector2D<T, U> {
43 pub x: T,
45 pub y: T,
47 #[doc(hidden)]
48 pub _unit: PhantomData<U>,
49}
50
51mint_vec!(Vector2D[x, y] = Vector2);
52
53impl<T: Copy, U> Copy for Vector2D<T, U> {}
54
55impl<T: Clone, U> Clone for Vector2D<T, U> {
56 fn clone(&self) -> Self {
57 Vector2D {
58 x: self.x.clone(),
59 y: self.y.clone(),
60 _unit: PhantomData,
61 }
62 }
63}
64
65#[cfg(feature = "malloc_size_of")]
66impl<T: MallocSizeOf, U> MallocSizeOf for Vector2D<T, U> {
67 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
68 self.x.size_of(ops) + self.y.size_of(ops)
69 }
70}
71
72#[cfg(feature = "serde")]
73impl<'de, T, U> serde::Deserialize<'de> for Vector2D<T, U>
74where
75 T: serde::Deserialize<'de>,
76{
77 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
78 where
79 D: serde::Deserializer<'de>,
80 {
81 let (x, y) = serde::Deserialize::deserialize(deserializer)?;
82 Ok(Vector2D {
83 x,
84 y,
85 _unit: PhantomData,
86 })
87 }
88}
89
90#[cfg(feature = "serde")]
91impl<T, U> serde::Serialize for Vector2D<T, U>
92where
93 T: serde::Serialize,
94{
95 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
96 where
97 S: serde::Serializer,
98 {
99 (&self.x, &self.y).serialize(serializer)
100 }
101}
102
103#[cfg(feature = "arbitrary")]
104impl<'a, T, U> arbitrary::Arbitrary<'a> for Vector2D<T, U>
105where
106 T: arbitrary::Arbitrary<'a>,
107{
108 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
109 let (x, y) = arbitrary::Arbitrary::arbitrary(u)?;
110 Ok(Vector2D {
111 x,
112 y,
113 _unit: PhantomData,
114 })
115 }
116}
117
118#[cfg(feature = "bytemuck")]
119unsafe impl<T: Zeroable, U> Zeroable for Vector2D<T, U> {}
120
121#[cfg(feature = "bytemuck")]
122unsafe impl<T: Pod, U: 'static> Pod for Vector2D<T, U> {}
123
124impl<T: Eq, U> Eq for Vector2D<T, U> {}
125
126impl<T: PartialEq, U> PartialEq for Vector2D<T, U> {
127 fn eq(&self, other: &Self) -> bool {
128 self.x == other.x && self.y == other.y
129 }
130}
131
132impl<T: Hash, U> Hash for Vector2D<T, U> {
133 fn hash<H: core::hash::Hasher>(&self, h: &mut H) {
134 self.x.hash(h);
135 self.y.hash(h);
136 }
137}
138
139impl<T: Zero, U> Zero for Vector2D<T, U> {
140 #[inline]
142 fn zero() -> Self {
143 Vector2D::new(Zero::zero(), Zero::zero())
144 }
145}
146
147impl<T: fmt::Debug, U> fmt::Debug for Vector2D<T, U> {
148 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
149 f.debug_tuple("").field(&self.x).field(&self.y).finish()
150 }
151}
152
153impl<T: Default, U> Default for Vector2D<T, U> {
154 fn default() -> Self {
155 Vector2D::new(Default::default(), Default::default())
156 }
157}
158
159impl<T, U> Vector2D<T, U> {
160 #[inline]
162 pub fn zero() -> Self
163 where
164 T: Zero,
165 {
166 Vector2D::new(Zero::zero(), Zero::zero())
167 }
168
169 #[inline]
171 pub fn one() -> Self
172 where
173 T: One,
174 {
175 Vector2D::new(One::one(), One::one())
176 }
177
178 #[inline]
180 pub const fn new(x: T, y: T) -> Self {
181 Vector2D {
182 x,
183 y,
184 _unit: PhantomData,
185 }
186 }
187
188 #[inline]
190 pub fn splat(v: T) -> Self
191 where
192 T: Clone,
193 {
194 Vector2D {
195 x: v.clone(),
196 y: v,
197 _unit: PhantomData,
198 }
199 }
200
201 pub fn from_angle_and_length(angle: Angle<T>, length: T) -> Self
203 where
204 T: Trig + Mul<Output = T> + Copy,
205 {
206 vec2(length * angle.radians.cos(), length * angle.radians.sin())
207 }
208
209 #[inline]
211 pub fn from_lengths(x: Length<T, U>, y: Length<T, U>) -> Self {
212 vec2(x.0, y.0)
213 }
214
215 #[inline]
217 pub fn from_untyped(p: Vector2D<T, UnknownUnit>) -> Self {
218 vec2(p.x, p.y)
219 }
220
221 #[inline]
234 pub fn map<V, F: FnMut(T) -> V>(self, mut f: F) -> Vector2D<V, U> {
235 vec2(f(self.x), f(self.y))
236 }
237
238 #[inline]
252 pub fn zip<V, F: FnMut(T, T) -> V>(self, rhs: Self, mut f: F) -> Vector2D<V, U> {
253 vec2(f(self.x, rhs.x), f(self.y, rhs.y))
254 }
255
256 pub fn abs(self) -> Self
277 where
278 T: Signed,
279 {
280 vec2(self.x.abs(), self.y.abs())
281 }
282
283 #[inline]
285 pub fn dot(self, other: Self) -> T
286 where
287 T: Add<Output = T> + Mul<Output = T>,
288 {
289 self.x * other.x + self.y * other.y
290 }
291
292 #[inline]
294 pub fn cross(self, other: Self) -> T
295 where
296 T: Sub<Output = T> + Mul<Output = T>,
297 {
298 self.x * other.y - self.y * other.x
299 }
300
301 #[inline]
303 pub fn component_mul(self, other: Self) -> Self
304 where
305 T: Mul<Output = T>,
306 {
307 vec2(self.x * other.x, self.y * other.y)
308 }
309
310 #[inline]
312 pub fn component_div(self, other: Self) -> Self
313 where
314 T: Div<Output = T>,
315 {
316 vec2(self.x / other.x, self.y / other.y)
317 }
318}
319
320impl<T: Copy, U> Vector2D<T, U> {
321 #[inline]
323 pub fn extend(self, z: T) -> Vector3D<T, U> {
324 vec3(self.x, self.y, z)
325 }
326
327 #[inline]
331 pub fn to_point(self) -> Point2D<T, U> {
332 Point2D {
333 x: self.x,
334 y: self.y,
335 _unit: PhantomData,
336 }
337 }
338
339 #[inline]
341 pub fn yx(self) -> Self {
342 vec2(self.y, self.x)
343 }
344
345 #[inline]
347 pub fn to_size(self) -> Size2D<T, U> {
348 size2(self.x, self.y)
349 }
350
351 #[inline]
353 pub fn to_untyped(self) -> Vector2D<T, UnknownUnit> {
354 vec2(self.x, self.y)
355 }
356
357 #[inline]
359 pub fn cast_unit<V>(self) -> Vector2D<T, V> {
360 vec2(self.x, self.y)
361 }
362
363 #[inline]
365 pub fn to_array(self) -> [T; 2] {
366 [self.x, self.y]
367 }
368
369 #[inline]
371 pub fn to_tuple(self) -> (T, T) {
372 (self.x, self.y)
373 }
374
375 #[inline]
377 pub fn to_3d(self) -> Vector3D<T, U>
378 where
379 T: Zero,
380 {
381 vec3(self.x, self.y, Zero::zero())
382 }
383
384 #[inline]
395 #[must_use]
396 pub fn round(self) -> Self
397 where
398 T: Round,
399 {
400 vec2(self.x.round(), self.y.round())
401 }
402
403 #[inline]
414 #[must_use]
415 pub fn ceil(self) -> Self
416 where
417 T: Ceil,
418 {
419 vec2(self.x.ceil(), self.y.ceil())
420 }
421
422 #[inline]
433 #[must_use]
434 pub fn floor(self) -> Self
435 where
436 T: Floor,
437 {
438 vec2(self.x.floor(), self.y.floor())
439 }
440
441 pub fn angle_from_x_axis(self) -> Angle<T>
447 where
448 T: Trig,
449 {
450 Angle::radians(Trig::fast_atan2(self.y, self.x))
451 }
452
453 #[inline]
455 pub fn to_transform(self) -> Transform2D<T, U, U>
456 where
457 T: Zero + One,
458 {
459 Transform2D::translation(self.x, self.y)
460 }
461}
462
463impl<T, U> Vector2D<T, U>
464where
465 T: Copy + Mul<T, Output = T> + Add<T, Output = T>,
466{
467 #[inline]
469 pub fn square_length(self) -> T {
470 self.x * self.x + self.y * self.y
471 }
472
473 #[inline]
477 pub fn project_onto_vector(self, onto: Self) -> Self
478 where
479 T: Sub<T, Output = T> + Div<T, Output = T>,
480 {
481 onto * (self.dot(onto) / onto.square_length())
482 }
483
484 pub fn angle_to(self, other: Self) -> Angle<T>
488 where
489 T: Sub<Output = T> + Trig,
490 {
491 Angle::radians(Trig::fast_atan2(self.cross(other), self.dot(other)))
492 }
493}
494
495impl<T: Float, U> Vector2D<T, U> {
496 #[inline]
498 #[must_use]
499 pub fn robust_normalize(self) -> Self {
500 let length = self.length();
501 if length.is_infinite() {
502 let scaled = self / T::max_value();
503 scaled / scaled.length()
504 } else {
505 self / length
506 }
507 }
508
509 #[inline]
511 pub fn is_finite(self) -> bool {
512 self.x.is_finite() && self.y.is_finite()
513 }
514}
515
516impl<T: Real, U> Vector2D<T, U> {
517 #[inline]
519 pub fn length(self) -> T {
520 self.square_length().sqrt()
521 }
522
523 #[inline]
525 #[must_use]
526 pub fn normalize(self) -> Self {
527 self / self.length()
528 }
529
530 #[inline]
535 #[must_use]
536 pub fn try_normalize(self) -> Option<Self> {
537 let len = self.length();
538 if len == T::zero() {
539 None
540 } else {
541 Some(self / len)
542 }
543 }
544
545 #[inline]
547 pub fn with_length(self, length: T) -> Self {
548 self.normalize() * length
549 }
550
551 #[inline]
553 pub fn with_max_length(self, max_length: T) -> Self {
554 let square_length = self.square_length();
555 if square_length > max_length * max_length {
556 return self * (max_length / square_length.sqrt());
557 }
558
559 self
560 }
561
562 #[inline]
564 pub fn with_min_length(self, min_length: T) -> Self {
565 let square_length = self.square_length();
566 if square_length < min_length * min_length {
567 return self * (min_length / square_length.sqrt());
568 }
569
570 self
571 }
572
573 #[inline]
575 pub fn clamp_length(self, min: T, max: T) -> Self {
576 debug_assert!(min <= max);
577 self.with_min_length(min).with_max_length(max)
578 }
579}
580
581impl<T, U> Vector2D<T, U>
582where
583 T: Copy + One + Add<Output = T> + Sub<Output = T> + Mul<Output = T>,
584{
585 #[inline]
603 pub fn lerp(self, other: Self, t: T) -> Self {
604 let one_t = T::one() - t;
605 self * one_t + other * t
606 }
607
608 #[inline]
610 pub fn reflect(self, normal: Self) -> Self {
611 let two = T::one() + T::one();
612 self - normal * two * self.dot(normal)
613 }
614}
615
616impl<T: PartialOrd, U> Vector2D<T, U> {
617 #[inline]
619 pub fn min(self, other: Self) -> Self {
620 vec2(min(self.x, other.x), min(self.y, other.y))
621 }
622
623 #[inline]
625 pub fn max(self, other: Self) -> Self {
626 vec2(max(self.x, other.x), max(self.y, other.y))
627 }
628
629 #[inline]
634 pub fn clamp(self, start: Self, end: Self) -> Self
635 where
636 T: Copy,
637 {
638 self.max(start).min(end)
639 }
640
641 #[inline]
643 pub fn greater_than(self, other: Self) -> BoolVector2D {
644 BoolVector2D {
645 x: self.x > other.x,
646 y: self.y > other.y,
647 }
648 }
649
650 #[inline]
652 pub fn lower_than(self, other: Self) -> BoolVector2D {
653 BoolVector2D {
654 x: self.x < other.x,
655 y: self.y < other.y,
656 }
657 }
658}
659
660impl<T: PartialEq, U> Vector2D<T, U> {
661 #[inline]
663 pub fn equal(self, other: Self) -> BoolVector2D {
664 BoolVector2D {
665 x: self.x == other.x,
666 y: self.y == other.y,
667 }
668 }
669
670 #[inline]
672 pub fn not_equal(self, other: Self) -> BoolVector2D {
673 BoolVector2D {
674 x: self.x != other.x,
675 y: self.y != other.y,
676 }
677 }
678}
679
680impl<T: NumCast + Copy, U> Vector2D<T, U> {
681 #[inline]
687 pub fn cast<NewT: NumCast>(self) -> Vector2D<NewT, U> {
688 self.try_cast().unwrap()
689 }
690
691 pub fn try_cast<NewT: NumCast>(self) -> Option<Vector2D<NewT, U>> {
697 match (NumCast::from(self.x), NumCast::from(self.y)) {
698 (Some(x), Some(y)) => Some(Vector2D::new(x, y)),
699 _ => None,
700 }
701 }
702
703 #[inline]
707 pub fn to_f32(self) -> Vector2D<f32, U> {
708 self.cast()
709 }
710
711 #[inline]
713 pub fn to_f64(self) -> Vector2D<f64, U> {
714 self.cast()
715 }
716
717 #[inline]
723 pub fn to_usize(self) -> Vector2D<usize, U> {
724 self.cast()
725 }
726
727 #[inline]
733 pub fn to_isize(self) -> Vector2D<isize, U> {
734 self.cast()
735 }
736
737 #[inline]
743 pub fn to_u32(self) -> Vector2D<u32, U> {
744 self.cast()
745 }
746
747 #[inline]
753 pub fn to_i32(self) -> Vector2D<i32, U> {
754 self.cast()
755 }
756
757 #[inline]
763 pub fn to_i64(self) -> Vector2D<i64, U> {
764 self.cast()
765 }
766}
767
768impl<T: Neg, U> Neg for Vector2D<T, U> {
769 type Output = Vector2D<T::Output, U>;
770
771 #[inline]
772 fn neg(self) -> Self::Output {
773 vec2(-self.x, -self.y)
774 }
775}
776
777impl<T: Add, U> Add for Vector2D<T, U> {
778 type Output = Vector2D<T::Output, U>;
779
780 #[inline]
781 fn add(self, other: Self) -> Self::Output {
782 Vector2D::new(self.x + other.x, self.y + other.y)
783 }
784}
785
786impl<T: Add + Copy, U> Add<&Self> for Vector2D<T, U> {
787 type Output = Vector2D<T::Output, U>;
788
789 #[inline]
790 fn add(self, other: &Self) -> Self::Output {
791 Vector2D::new(self.x + other.x, self.y + other.y)
792 }
793}
794
795impl<T: Add<Output = T> + Zero, U> Sum for Vector2D<T, U> {
796 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
797 iter.fold(Self::zero(), Add::add)
798 }
799}
800
801impl<'a, T: 'a + Add<Output = T> + Copy + Zero, U: 'a> Sum<&'a Self> for Vector2D<T, U> {
802 fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
803 iter.fold(Self::zero(), Add::add)
804 }
805}
806
807impl<T: Copy + Add<T, Output = T>, U> AddAssign for Vector2D<T, U> {
808 #[inline]
809 fn add_assign(&mut self, other: Self) {
810 *self = *self + other;
811 }
812}
813
814impl<T: Sub, U> Sub for Vector2D<T, U> {
815 type Output = Vector2D<T::Output, U>;
816
817 #[inline]
818 fn sub(self, other: Self) -> Self::Output {
819 vec2(self.x - other.x, self.y - other.y)
820 }
821}
822
823impl<T: Copy + Sub<T, Output = T>, U> SubAssign<Vector2D<T, U>> for Vector2D<T, U> {
824 #[inline]
825 fn sub_assign(&mut self, other: Self) {
826 *self = *self - other;
827 }
828}
829
830impl<T: Copy + Mul, U> Mul<T> for Vector2D<T, U> {
831 type Output = Vector2D<T::Output, U>;
832
833 #[inline]
834 fn mul(self, scale: T) -> Self::Output {
835 vec2(self.x * scale, self.y * scale)
836 }
837}
838
839impl<T: Copy + Mul<T, Output = T>, U> MulAssign<T> for Vector2D<T, U> {
840 #[inline]
841 fn mul_assign(&mut self, scale: T) {
842 *self = *self * scale;
843 }
844}
845
846impl<T: Copy + Mul, U1, U2> Mul<Scale<T, U1, U2>> for Vector2D<T, U1> {
847 type Output = Vector2D<T::Output, U2>;
848
849 #[inline]
850 fn mul(self, scale: Scale<T, U1, U2>) -> Self::Output {
851 vec2(self.x * scale.0, self.y * scale.0)
852 }
853}
854
855impl<T: Copy + MulAssign, U> MulAssign<Scale<T, U, U>> for Vector2D<T, U> {
856 #[inline]
857 fn mul_assign(&mut self, scale: Scale<T, U, U>) {
858 self.x *= scale.0;
859 self.y *= scale.0;
860 }
861}
862
863impl<T: Copy + Div, U> Div<T> for Vector2D<T, U> {
864 type Output = Vector2D<T::Output, U>;
865
866 #[inline]
867 fn div(self, scale: T) -> Self::Output {
868 vec2(self.x / scale, self.y / scale)
869 }
870}
871
872impl<T: Copy + Div<T, Output = T>, U> DivAssign<T> for Vector2D<T, U> {
873 #[inline]
874 fn div_assign(&mut self, scale: T) {
875 *self = *self / scale;
876 }
877}
878
879impl<T: Copy + Div, U1, U2> Div<Scale<T, U1, U2>> for Vector2D<T, U2> {
880 type Output = Vector2D<T::Output, U1>;
881
882 #[inline]
883 fn div(self, scale: Scale<T, U1, U2>) -> Self::Output {
884 vec2(self.x / scale.0, self.y / scale.0)
885 }
886}
887
888impl<T: Copy + DivAssign, U> DivAssign<Scale<T, U, U>> for Vector2D<T, U> {
889 #[inline]
890 fn div_assign(&mut self, scale: Scale<T, U, U>) {
891 self.x /= scale.0;
892 self.y /= scale.0;
893 }
894}
895
896impl<T: Round, U> Round for Vector2D<T, U> {
897 #[inline]
899 fn round(self) -> Self {
900 self.round()
901 }
902}
903
904impl<T: Ceil, U> Ceil for Vector2D<T, U> {
905 #[inline]
907 fn ceil(self) -> Self {
908 self.ceil()
909 }
910}
911
912impl<T: Floor, U> Floor for Vector2D<T, U> {
913 #[inline]
915 fn floor(self) -> Self {
916 self.floor()
917 }
918}
919
920impl<T: ApproxEq<T>, U> ApproxEq<Vector2D<T, U>> for Vector2D<T, U> {
921 #[inline]
922 fn approx_epsilon() -> Self {
923 vec2(T::approx_epsilon(), T::approx_epsilon())
924 }
925
926 #[inline]
927 fn approx_eq_eps(&self, other: &Self, eps: &Self) -> bool {
928 self.x.approx_eq_eps(&other.x, &eps.x) && self.y.approx_eq_eps(&other.y, &eps.y)
929 }
930}
931
932impl<T, U> From<Vector2D<T, U>> for [T; 2] {
933 fn from(v: Vector2D<T, U>) -> Self {
934 [v.x, v.y]
935 }
936}
937
938impl<T, U> From<[T; 2]> for Vector2D<T, U> {
939 fn from([x, y]: [T; 2]) -> Self {
940 vec2(x, y)
941 }
942}
943
944impl<T, U> From<Vector2D<T, U>> for (T, T) {
945 fn from(v: Vector2D<T, U>) -> Self {
946 (v.x, v.y)
947 }
948}
949
950impl<T, U> From<(T, T)> for Vector2D<T, U> {
951 fn from(tuple: (T, T)) -> Self {
952 vec2(tuple.0, tuple.1)
953 }
954}
955
956impl<T, U> From<Size2D<T, U>> for Vector2D<T, U> {
957 fn from(s: Size2D<T, U>) -> Self {
958 vec2(s.width, s.height)
959 }
960}
961
962#[repr(C)]
964pub struct Vector3D<T, U> {
965 pub x: T,
967 pub y: T,
969 pub z: T,
971 #[doc(hidden)]
972 pub _unit: PhantomData<U>,
973}
974
975mint_vec!(Vector3D[x, y, z] = Vector3);
976
977impl<T: Copy, U> Copy for Vector3D<T, U> {}
978
979impl<T: Clone, U> Clone for Vector3D<T, U> {
980 fn clone(&self) -> Self {
981 Vector3D {
982 x: self.x.clone(),
983 y: self.y.clone(),
984 z: self.z.clone(),
985 _unit: PhantomData,
986 }
987 }
988}
989
990#[cfg(feature = "serde")]
991impl<'de, T, U> serde::Deserialize<'de> for Vector3D<T, U>
992where
993 T: serde::Deserialize<'de>,
994{
995 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
996 where
997 D: serde::Deserializer<'de>,
998 {
999 let (x, y, z) = serde::Deserialize::deserialize(deserializer)?;
1000 Ok(Vector3D {
1001 x,
1002 y,
1003 z,
1004 _unit: PhantomData,
1005 })
1006 }
1007}
1008
1009#[cfg(feature = "serde")]
1010impl<T, U> serde::Serialize for Vector3D<T, U>
1011where
1012 T: serde::Serialize,
1013{
1014 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1015 where
1016 S: serde::Serializer,
1017 {
1018 (&self.x, &self.y, &self.z).serialize(serializer)
1019 }
1020}
1021
1022#[cfg(feature = "arbitrary")]
1023impl<'a, T, U> arbitrary::Arbitrary<'a> for Vector3D<T, U>
1024where
1025 T: arbitrary::Arbitrary<'a>,
1026{
1027 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
1028 let (x, y, z) = arbitrary::Arbitrary::arbitrary(u)?;
1029 Ok(Vector3D {
1030 x,
1031 y,
1032 z,
1033 _unit: PhantomData,
1034 })
1035 }
1036}
1037
1038#[cfg(feature = "bytemuck")]
1039unsafe impl<T: Zeroable, U> Zeroable for Vector3D<T, U> {}
1040
1041#[cfg(feature = "bytemuck")]
1042unsafe impl<T: Pod, U: 'static> Pod for Vector3D<T, U> {}
1043
1044#[cfg(feature = "malloc_size_of")]
1045impl<T: MallocSizeOf, U> MallocSizeOf for Vector3D<T, U> {
1046 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
1047 self.x.size_of(ops) + self.y.size_of(ops) + self.z.size_of(ops)
1048 }
1049}
1050
1051impl<T: Eq, U> Eq for Vector3D<T, U> {}
1052
1053impl<T: PartialEq, U> PartialEq for Vector3D<T, U> {
1054 fn eq(&self, other: &Self) -> bool {
1055 self.x == other.x && self.y == other.y && self.z == other.z
1056 }
1057}
1058
1059impl<T: Hash, U> Hash for Vector3D<T, U> {
1060 fn hash<H: core::hash::Hasher>(&self, h: &mut H) {
1061 self.x.hash(h);
1062 self.y.hash(h);
1063 self.z.hash(h);
1064 }
1065}
1066
1067impl<T: Zero, U> Zero for Vector3D<T, U> {
1068 #[inline]
1070 fn zero() -> Self {
1071 vec3(Zero::zero(), Zero::zero(), Zero::zero())
1072 }
1073}
1074
1075impl<T: fmt::Debug, U> fmt::Debug for Vector3D<T, U> {
1076 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1077 f.debug_tuple("")
1078 .field(&self.x)
1079 .field(&self.y)
1080 .field(&self.z)
1081 .finish()
1082 }
1083}
1084
1085impl<T: Default, U> Default for Vector3D<T, U> {
1086 fn default() -> Self {
1087 Vector3D::new(Default::default(), Default::default(), Default::default())
1088 }
1089}
1090
1091impl<T, U> Vector3D<T, U> {
1092 #[inline]
1094 pub fn zero() -> Self
1095 where
1096 T: Zero,
1097 {
1098 vec3(Zero::zero(), Zero::zero(), Zero::zero())
1099 }
1100
1101 #[inline]
1103 pub fn one() -> Self
1104 where
1105 T: One,
1106 {
1107 vec3(One::one(), One::one(), One::one())
1108 }
1109
1110 #[inline]
1112 pub const fn new(x: T, y: T, z: T) -> Self {
1113 Vector3D {
1114 x,
1115 y,
1116 z,
1117 _unit: PhantomData,
1118 }
1119 }
1120 #[inline]
1122 pub fn splat(v: T) -> Self
1123 where
1124 T: Clone,
1125 {
1126 Vector3D {
1127 x: v.clone(),
1128 y: v.clone(),
1129 z: v,
1130 _unit: PhantomData,
1131 }
1132 }
1133
1134 #[inline]
1136 pub fn from_lengths(x: Length<T, U>, y: Length<T, U>, z: Length<T, U>) -> Vector3D<T, U> {
1137 vec3(x.0, y.0, z.0)
1138 }
1139
1140 #[inline]
1142 pub fn from_untyped(p: Vector3D<T, UnknownUnit>) -> Self {
1143 vec3(p.x, p.y, p.z)
1144 }
1145
1146 #[inline]
1159 pub fn map<V, F: FnMut(T) -> V>(self, mut f: F) -> Vector3D<V, U> {
1160 vec3(f(self.x), f(self.y), f(self.z))
1161 }
1162
1163 #[inline]
1177 pub fn zip<V, F: FnMut(T, T) -> V>(self, rhs: Self, mut f: F) -> Vector3D<V, U> {
1178 vec3(f(self.x, rhs.x), f(self.y, rhs.y), f(self.z, rhs.z))
1179 }
1180
1181 pub fn abs(self) -> Self
1203 where
1204 T: Signed,
1205 {
1206 vec3(self.x.abs(), self.y.abs(), self.z.abs())
1207 }
1208
1209 #[inline]
1211 pub fn dot(self, other: Self) -> T
1212 where
1213 T: Add<Output = T> + Mul<Output = T>,
1214 {
1215 self.x * other.x + self.y * other.y + self.z * other.z
1216 }
1217}
1218
1219impl<T: Copy, U> Vector3D<T, U> {
1220 #[inline]
1222 pub fn cross(self, other: Self) -> Self
1223 where
1224 T: Sub<Output = T> + Mul<Output = T>,
1225 {
1226 vec3(
1227 self.y * other.z - self.z * other.y,
1228 self.z * other.x - self.x * other.z,
1229 self.x * other.y - self.y * other.x,
1230 )
1231 }
1232
1233 #[inline]
1235 pub fn component_mul(self, other: Self) -> Self
1236 where
1237 T: Mul<Output = T>,
1238 {
1239 vec3(self.x * other.x, self.y * other.y, self.z * other.z)
1240 }
1241
1242 #[inline]
1244 pub fn component_div(self, other: Self) -> Self
1245 where
1246 T: Div<Output = T>,
1247 {
1248 vec3(self.x / other.x, self.y / other.y, self.z / other.z)
1249 }
1250
1251 #[inline]
1255 pub fn to_point(self) -> Point3D<T, U> {
1256 point3(self.x, self.y, self.z)
1257 }
1258
1259 #[inline]
1261 pub fn xy(self) -> Vector2D<T, U> {
1262 vec2(self.x, self.y)
1263 }
1264
1265 #[inline]
1267 pub fn xz(self) -> Vector2D<T, U> {
1268 vec2(self.x, self.z)
1269 }
1270
1271 #[inline]
1273 pub fn yz(self) -> Vector2D<T, U> {
1274 vec2(self.y, self.z)
1275 }
1276
1277 #[inline]
1279 pub fn to_array(self) -> [T; 3] {
1280 [self.x, self.y, self.z]
1281 }
1282
1283 #[inline]
1285 pub fn to_array_4d(self) -> [T; 4]
1286 where
1287 T: Zero,
1288 {
1289 [self.x, self.y, self.z, Zero::zero()]
1290 }
1291
1292 #[inline]
1294 pub fn to_tuple(self) -> (T, T, T) {
1295 (self.x, self.y, self.z)
1296 }
1297
1298 #[inline]
1300 pub fn to_tuple_4d(self) -> (T, T, T, T)
1301 where
1302 T: Zero,
1303 {
1304 (self.x, self.y, self.z, Zero::zero())
1305 }
1306
1307 #[inline]
1309 pub fn to_untyped(self) -> Vector3D<T, UnknownUnit> {
1310 vec3(self.x, self.y, self.z)
1311 }
1312
1313 #[inline]
1315 pub fn cast_unit<V>(self) -> Vector3D<T, V> {
1316 vec3(self.x, self.y, self.z)
1317 }
1318
1319 #[inline]
1321 pub fn to_2d(self) -> Vector2D<T, U> {
1322 self.xy()
1323 }
1324
1325 #[inline]
1336 #[must_use]
1337 pub fn round(self) -> Self
1338 where
1339 T: Round,
1340 {
1341 vec3(self.x.round(), self.y.round(), self.z.round())
1342 }
1343
1344 #[inline]
1355 #[must_use]
1356 pub fn ceil(self) -> Self
1357 where
1358 T: Ceil,
1359 {
1360 vec3(self.x.ceil(), self.y.ceil(), self.z.ceil())
1361 }
1362
1363 #[inline]
1374 #[must_use]
1375 pub fn floor(self) -> Self
1376 where
1377 T: Floor,
1378 {
1379 vec3(self.x.floor(), self.y.floor(), self.z.floor())
1380 }
1381
1382 #[inline]
1384 pub fn to_transform(self) -> Transform3D<T, U, U>
1385 where
1386 T: Zero + One,
1387 {
1388 Transform3D::translation(self.x, self.y, self.z)
1389 }
1390}
1391
1392impl<T, U> Vector3D<T, U>
1393where
1394 T: Copy + Mul<T, Output = T> + Add<T, Output = T>,
1395{
1396 #[inline]
1398 pub fn square_length(self) -> T {
1399 self.x * self.x + self.y * self.y + self.z * self.z
1400 }
1401
1402 #[inline]
1406 pub fn project_onto_vector(self, onto: Self) -> Self
1407 where
1408 T: Sub<T, Output = T> + Div<T, Output = T>,
1409 {
1410 onto * (self.dot(onto) / onto.square_length())
1411 }
1412}
1413
1414impl<T: Float, U> Vector3D<T, U> {
1415 #[inline]
1417 #[must_use]
1418 pub fn robust_normalize(self) -> Self {
1419 let length = self.length();
1420 if length.is_infinite() {
1421 let scaled = self / T::max_value();
1422 scaled / scaled.length()
1423 } else {
1424 self / length
1425 }
1426 }
1427
1428 #[inline]
1430 pub fn is_finite(self) -> bool {
1431 self.x.is_finite() && self.y.is_finite() && self.z.is_finite()
1432 }
1433}
1434
1435impl<T: Real, U> Vector3D<T, U> {
1436 pub fn angle_to(self, other: Self) -> Angle<T>
1440 where
1441 T: Trig,
1442 {
1443 Angle::radians(Trig::fast_atan2(
1444 self.cross(other).length(),
1445 self.dot(other),
1446 ))
1447 }
1448
1449 #[inline]
1451 pub fn length(self) -> T {
1452 self.square_length().sqrt()
1453 }
1454
1455 #[inline]
1457 #[must_use]
1458 pub fn normalize(self) -> Self {
1459 self / self.length()
1460 }
1461
1462 #[inline]
1467 #[must_use]
1468 pub fn try_normalize(self) -> Option<Self> {
1469 let len = self.length();
1470 if len == T::zero() {
1471 None
1472 } else {
1473 Some(self / len)
1474 }
1475 }
1476
1477 #[inline]
1479 pub fn with_max_length(self, max_length: T) -> Self {
1480 let square_length = self.square_length();
1481 if square_length > max_length * max_length {
1482 return self * (max_length / square_length.sqrt());
1483 }
1484
1485 self
1486 }
1487
1488 #[inline]
1490 pub fn with_min_length(self, min_length: T) -> Self {
1491 let square_length = self.square_length();
1492 if square_length < min_length * min_length {
1493 return self * (min_length / square_length.sqrt());
1494 }
1495
1496 self
1497 }
1498
1499 #[inline]
1501 pub fn clamp_length(self, min: T, max: T) -> Self {
1502 debug_assert!(min <= max);
1503 self.with_min_length(min).with_max_length(max)
1504 }
1505}
1506
1507impl<T, U> Vector3D<T, U>
1508where
1509 T: Copy + One + Add<Output = T> + Sub<Output = T> + Mul<Output = T>,
1510{
1511 #[inline]
1529 pub fn lerp(self, other: Self, t: T) -> Self {
1530 let one_t = T::one() - t;
1531 self * one_t + other * t
1532 }
1533
1534 #[inline]
1536 pub fn reflect(self, normal: Self) -> Self {
1537 let two = T::one() + T::one();
1538 self - normal * two * self.dot(normal)
1539 }
1540}
1541
1542impl<T: PartialOrd, U> Vector3D<T, U> {
1543 #[inline]
1545 pub fn min(self, other: Self) -> Self {
1546 vec3(
1547 min(self.x, other.x),
1548 min(self.y, other.y),
1549 min(self.z, other.z),
1550 )
1551 }
1552
1553 #[inline]
1555 pub fn max(self, other: Self) -> Self {
1556 vec3(
1557 max(self.x, other.x),
1558 max(self.y, other.y),
1559 max(self.z, other.z),
1560 )
1561 }
1562
1563 #[inline]
1568 pub fn clamp(self, start: Self, end: Self) -> Self
1569 where
1570 T: Copy,
1571 {
1572 self.max(start).min(end)
1573 }
1574
1575 #[inline]
1577 pub fn greater_than(self, other: Self) -> BoolVector3D {
1578 BoolVector3D {
1579 x: self.x > other.x,
1580 y: self.y > other.y,
1581 z: self.z > other.z,
1582 }
1583 }
1584
1585 #[inline]
1587 pub fn lower_than(self, other: Self) -> BoolVector3D {
1588 BoolVector3D {
1589 x: self.x < other.x,
1590 y: self.y < other.y,
1591 z: self.z < other.z,
1592 }
1593 }
1594}
1595
1596impl<T: PartialEq, U> Vector3D<T, U> {
1597 #[inline]
1599 pub fn equal(self, other: Self) -> BoolVector3D {
1600 BoolVector3D {
1601 x: self.x == other.x,
1602 y: self.y == other.y,
1603 z: self.z == other.z,
1604 }
1605 }
1606
1607 #[inline]
1609 pub fn not_equal(self, other: Self) -> BoolVector3D {
1610 BoolVector3D {
1611 x: self.x != other.x,
1612 y: self.y != other.y,
1613 z: self.z != other.z,
1614 }
1615 }
1616}
1617
1618impl<T: NumCast + Copy, U> Vector3D<T, U> {
1619 #[inline]
1625 pub fn cast<NewT: NumCast>(self) -> Vector3D<NewT, U> {
1626 self.try_cast().unwrap()
1627 }
1628
1629 pub fn try_cast<NewT: NumCast>(self) -> Option<Vector3D<NewT, U>> {
1635 match (
1636 NumCast::from(self.x),
1637 NumCast::from(self.y),
1638 NumCast::from(self.z),
1639 ) {
1640 (Some(x), Some(y), Some(z)) => Some(vec3(x, y, z)),
1641 _ => None,
1642 }
1643 }
1644
1645 #[inline]
1649 pub fn to_f32(self) -> Vector3D<f32, U> {
1650 self.cast()
1651 }
1652
1653 #[inline]
1655 pub fn to_f64(self) -> Vector3D<f64, U> {
1656 self.cast()
1657 }
1658
1659 #[inline]
1665 pub fn to_usize(self) -> Vector3D<usize, U> {
1666 self.cast()
1667 }
1668
1669 #[inline]
1675 pub fn to_isize(self) -> Vector3D<isize, U> {
1676 self.cast()
1677 }
1678
1679 #[inline]
1685 pub fn to_u32(self) -> Vector3D<u32, U> {
1686 self.cast()
1687 }
1688
1689 #[inline]
1695 pub fn to_i32(self) -> Vector3D<i32, U> {
1696 self.cast()
1697 }
1698
1699 #[inline]
1705 pub fn to_i64(self) -> Vector3D<i64, U> {
1706 self.cast()
1707 }
1708}
1709
1710impl<T: Neg, U> Neg for Vector3D<T, U> {
1711 type Output = Vector3D<T::Output, U>;
1712
1713 #[inline]
1714 fn neg(self) -> Self::Output {
1715 vec3(-self.x, -self.y, -self.z)
1716 }
1717}
1718
1719impl<T: Add, U> Add for Vector3D<T, U> {
1720 type Output = Vector3D<T::Output, U>;
1721
1722 #[inline]
1723 fn add(self, other: Self) -> Self::Output {
1724 vec3(self.x + other.x, self.y + other.y, self.z + other.z)
1725 }
1726}
1727
1728impl<'a, T: 'a + Add + Copy, U: 'a> Add<&Self> for Vector3D<T, U> {
1729 type Output = Vector3D<T::Output, U>;
1730
1731 #[inline]
1732 fn add(self, other: &Self) -> Self::Output {
1733 vec3(self.x + other.x, self.y + other.y, self.z + other.z)
1734 }
1735}
1736
1737impl<T: Add<Output = T> + Zero, U> Sum for Vector3D<T, U> {
1738 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
1739 iter.fold(Self::zero(), Add::add)
1740 }
1741}
1742
1743impl<'a, T: 'a + Add<Output = T> + Copy + Zero, U: 'a> Sum<&'a Self> for Vector3D<T, U> {
1744 fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
1745 iter.fold(Self::zero(), Add::add)
1746 }
1747}
1748
1749impl<T: Copy + Add<T, Output = T>, U> AddAssign for Vector3D<T, U> {
1750 #[inline]
1751 fn add_assign(&mut self, other: Self) {
1752 *self = *self + other;
1753 }
1754}
1755
1756impl<T: Sub, U> Sub for Vector3D<T, U> {
1757 type Output = Vector3D<T::Output, U>;
1758
1759 #[inline]
1760 fn sub(self, other: Self) -> Self::Output {
1761 vec3(self.x - other.x, self.y - other.y, self.z - other.z)
1762 }
1763}
1764
1765impl<T: Copy + Sub<T, Output = T>, U> SubAssign<Vector3D<T, U>> for Vector3D<T, U> {
1766 #[inline]
1767 fn sub_assign(&mut self, other: Self) {
1768 *self = *self - other;
1769 }
1770}
1771
1772impl<T: Copy + Mul, U> Mul<T> for Vector3D<T, U> {
1773 type Output = Vector3D<T::Output, U>;
1774
1775 #[inline]
1776 fn mul(self, scale: T) -> Self::Output {
1777 vec3(self.x * scale, self.y * scale, self.z * scale)
1778 }
1779}
1780
1781impl<T: Copy + Mul<T, Output = T>, U> MulAssign<T> for Vector3D<T, U> {
1782 #[inline]
1783 fn mul_assign(&mut self, scale: T) {
1784 *self = *self * scale;
1785 }
1786}
1787
1788impl<T: Copy + Mul, U1, U2> Mul<Scale<T, U1, U2>> for Vector3D<T, U1> {
1789 type Output = Vector3D<T::Output, U2>;
1790
1791 #[inline]
1792 fn mul(self, scale: Scale<T, U1, U2>) -> Self::Output {
1793 vec3(self.x * scale.0, self.y * scale.0, self.z * scale.0)
1794 }
1795}
1796
1797impl<T: Copy + MulAssign, U> MulAssign<Scale<T, U, U>> for Vector3D<T, U> {
1798 #[inline]
1799 fn mul_assign(&mut self, scale: Scale<T, U, U>) {
1800 self.x *= scale.0;
1801 self.y *= scale.0;
1802 self.z *= scale.0;
1803 }
1804}
1805
1806impl<T: Copy + Div, U> Div<T> for Vector3D<T, U> {
1807 type Output = Vector3D<T::Output, U>;
1808
1809 #[inline]
1810 fn div(self, scale: T) -> Self::Output {
1811 vec3(self.x / scale, self.y / scale, self.z / scale)
1812 }
1813}
1814
1815impl<T: Copy + Div<T, Output = T>, U> DivAssign<T> for Vector3D<T, U> {
1816 #[inline]
1817 fn div_assign(&mut self, scale: T) {
1818 *self = *self / scale;
1819 }
1820}
1821
1822impl<T: Copy + Div, U1, U2> Div<Scale<T, U1, U2>> for Vector3D<T, U2> {
1823 type Output = Vector3D<T::Output, U1>;
1824
1825 #[inline]
1826 fn div(self, scale: Scale<T, U1, U2>) -> Self::Output {
1827 vec3(self.x / scale.0, self.y / scale.0, self.z / scale.0)
1828 }
1829}
1830
1831impl<T: Copy + DivAssign, U> DivAssign<Scale<T, U, U>> for Vector3D<T, U> {
1832 #[inline]
1833 fn div_assign(&mut self, scale: Scale<T, U, U>) {
1834 self.x /= scale.0;
1835 self.y /= scale.0;
1836 self.z /= scale.0;
1837 }
1838}
1839
1840impl<T: Round, U> Round for Vector3D<T, U> {
1841 #[inline]
1843 fn round(self) -> Self {
1844 self.round()
1845 }
1846}
1847
1848impl<T: Ceil, U> Ceil for Vector3D<T, U> {
1849 #[inline]
1851 fn ceil(self) -> Self {
1852 self.ceil()
1853 }
1854}
1855
1856impl<T: Floor, U> Floor for Vector3D<T, U> {
1857 #[inline]
1859 fn floor(self) -> Self {
1860 self.floor()
1861 }
1862}
1863
1864impl<T: ApproxEq<T>, U> ApproxEq<Vector3D<T, U>> for Vector3D<T, U> {
1865 #[inline]
1866 fn approx_epsilon() -> Self {
1867 vec3(
1868 T::approx_epsilon(),
1869 T::approx_epsilon(),
1870 T::approx_epsilon(),
1871 )
1872 }
1873
1874 #[inline]
1875 fn approx_eq_eps(&self, other: &Self, eps: &Self) -> bool {
1876 self.x.approx_eq_eps(&other.x, &eps.x)
1877 && self.y.approx_eq_eps(&other.y, &eps.y)
1878 && self.z.approx_eq_eps(&other.z, &eps.z)
1879 }
1880}
1881
1882impl<T, U> From<Vector3D<T, U>> for [T; 3] {
1883 fn from(v: Vector3D<T, U>) -> Self {
1884 [v.x, v.y, v.z]
1885 }
1886}
1887
1888impl<T, U> From<[T; 3]> for Vector3D<T, U> {
1889 fn from([x, y, z]: [T; 3]) -> Self {
1890 vec3(x, y, z)
1891 }
1892}
1893
1894impl<T, U> From<Vector3D<T, U>> for (T, T, T) {
1895 fn from(v: Vector3D<T, U>) -> Self {
1896 (v.x, v.y, v.z)
1897 }
1898}
1899
1900impl<T, U> From<(T, T, T)> for Vector3D<T, U> {
1901 fn from(tuple: (T, T, T)) -> Self {
1902 vec3(tuple.0, tuple.1, tuple.2)
1903 }
1904}
1905
1906#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1908pub struct BoolVector2D {
1909 pub x: bool,
1910 pub y: bool,
1911}
1912
1913#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1915pub struct BoolVector3D {
1916 pub x: bool,
1917 pub y: bool,
1918 pub z: bool,
1919}
1920
1921impl BoolVector2D {
1922 #[inline]
1924 pub fn all(self) -> bool {
1925 self.x && self.y
1926 }
1927
1928 #[inline]
1930 pub fn any(self) -> bool {
1931 self.x || self.y
1932 }
1933
1934 #[inline]
1936 pub fn none(self) -> bool {
1937 !self.any()
1938 }
1939
1940 #[inline]
1942 pub fn and(self, other: Self) -> Self {
1943 BoolVector2D {
1944 x: self.x && other.x,
1945 y: self.y && other.y,
1946 }
1947 }
1948
1949 #[inline]
1951 pub fn or(self, other: Self) -> Self {
1952 BoolVector2D {
1953 x: self.x || other.x,
1954 y: self.y || other.y,
1955 }
1956 }
1957
1958 #[inline]
1960 pub fn not(self) -> Self {
1961 BoolVector2D {
1962 x: !self.x,
1963 y: !self.y,
1964 }
1965 }
1966
1967 #[inline]
1970 pub fn select_point<T, U>(self, a: Point2D<T, U>, b: Point2D<T, U>) -> Point2D<T, U> {
1971 point2(
1972 if self.x { a.x } else { b.x },
1973 if self.y { a.y } else { b.y },
1974 )
1975 }
1976
1977 #[inline]
1980 pub fn select_vector<T, U>(self, a: Vector2D<T, U>, b: Vector2D<T, U>) -> Vector2D<T, U> {
1981 vec2(
1982 if self.x { a.x } else { b.x },
1983 if self.y { a.y } else { b.y },
1984 )
1985 }
1986
1987 #[inline]
1990 pub fn select_size<T, U>(self, a: Size2D<T, U>, b: Size2D<T, U>) -> Size2D<T, U> {
1991 size2(
1992 if self.x { a.width } else { b.width },
1993 if self.y { a.height } else { b.height },
1994 )
1995 }
1996}
1997
1998impl BoolVector3D {
1999 #[inline]
2001 pub fn all(self) -> bool {
2002 self.x && self.y && self.z
2003 }
2004
2005 #[inline]
2007 pub fn any(self) -> bool {
2008 self.x || self.y || self.z
2009 }
2010
2011 #[inline]
2013 pub fn none(self) -> bool {
2014 !self.any()
2015 }
2016
2017 #[inline]
2019 pub fn and(self, other: Self) -> Self {
2020 BoolVector3D {
2021 x: self.x && other.x,
2022 y: self.y && other.y,
2023 z: self.z && other.z,
2024 }
2025 }
2026
2027 #[inline]
2029 pub fn or(self, other: Self) -> Self {
2030 BoolVector3D {
2031 x: self.x || other.x,
2032 y: self.y || other.y,
2033 z: self.z || other.z,
2034 }
2035 }
2036
2037 #[inline]
2039 pub fn not(self) -> Self {
2040 BoolVector3D {
2041 x: !self.x,
2042 y: !self.y,
2043 z: !self.z,
2044 }
2045 }
2046
2047 #[inline]
2050 pub fn select_point<T, U>(self, a: Point3D<T, U>, b: Point3D<T, U>) -> Point3D<T, U> {
2051 point3(
2052 if self.x { a.x } else { b.x },
2053 if self.y { a.y } else { b.y },
2054 if self.z { a.z } else { b.z },
2055 )
2056 }
2057
2058 #[inline]
2061 pub fn select_vector<T, U>(self, a: Vector3D<T, U>, b: Vector3D<T, U>) -> Vector3D<T, U> {
2062 vec3(
2063 if self.x { a.x } else { b.x },
2064 if self.y { a.y } else { b.y },
2065 if self.z { a.z } else { b.z },
2066 )
2067 }
2068
2069 #[inline]
2072 #[must_use]
2073 pub fn select_size<T, U>(self, a: Size3D<T, U>, b: Size3D<T, U>) -> Size3D<T, U> {
2074 size3(
2075 if self.x { a.width } else { b.width },
2076 if self.y { a.height } else { b.height },
2077 if self.z { a.depth } else { b.depth },
2078 )
2079 }
2080
2081 #[inline]
2083 pub fn xy(self) -> BoolVector2D {
2084 BoolVector2D {
2085 x: self.x,
2086 y: self.y,
2087 }
2088 }
2089
2090 #[inline]
2092 pub fn xz(self) -> BoolVector2D {
2093 BoolVector2D {
2094 x: self.x,
2095 y: self.z,
2096 }
2097 }
2098
2099 #[inline]
2101 pub fn yz(self) -> BoolVector2D {
2102 BoolVector2D {
2103 x: self.y,
2104 y: self.z,
2105 }
2106 }
2107}
2108
2109#[cfg(feature = "arbitrary")]
2110impl<'a> arbitrary::Arbitrary<'a> for BoolVector2D {
2111 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
2112 Ok(BoolVector2D {
2113 x: arbitrary::Arbitrary::arbitrary(u)?,
2114 y: arbitrary::Arbitrary::arbitrary(u)?,
2115 })
2116 }
2117}
2118
2119#[cfg(feature = "arbitrary")]
2120impl<'a> arbitrary::Arbitrary<'a> for BoolVector3D {
2121 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
2122 Ok(BoolVector3D {
2123 x: arbitrary::Arbitrary::arbitrary(u)?,
2124 y: arbitrary::Arbitrary::arbitrary(u)?,
2125 z: arbitrary::Arbitrary::arbitrary(u)?,
2126 })
2127 }
2128}
2129
2130#[inline]
2132pub const fn vec2<T, U>(x: T, y: T) -> Vector2D<T, U> {
2133 Vector2D {
2134 x,
2135 y,
2136 _unit: PhantomData,
2137 }
2138}
2139
2140#[inline]
2142pub const fn vec3<T, U>(x: T, y: T, z: T) -> Vector3D<T, U> {
2143 Vector3D {
2144 x,
2145 y,
2146 z,
2147 _unit: PhantomData,
2148 }
2149}
2150
2151#[inline]
2153pub const fn bvec2(x: bool, y: bool) -> BoolVector2D {
2154 BoolVector2D { x, y }
2155}
2156
2157#[inline]
2159pub const fn bvec3(x: bool, y: bool, z: bool) -> BoolVector3D {
2160 BoolVector3D { x, y, z }
2161}
2162
2163#[cfg(test)]
2164mod vector2d {
2165 use crate::scale::Scale;
2166 use crate::{default, vec2};
2167
2168 #[cfg(feature = "mint")]
2169 use mint;
2170 type Vec2 = default::Vector2D<f32>;
2171
2172 #[test]
2173 pub fn test_scalar_mul() {
2174 let p1: Vec2 = vec2(3.0, 5.0);
2175
2176 let result = p1 * 5.0;
2177
2178 assert_eq!(result, Vec2::new(15.0, 25.0));
2179 }
2180
2181 #[test]
2182 pub fn test_dot() {
2183 let p1: Vec2 = vec2(2.0, 7.0);
2184 let p2: Vec2 = vec2(13.0, 11.0);
2185 assert_eq!(p1.dot(p2), 103.0);
2186 }
2187
2188 #[test]
2189 pub fn test_cross() {
2190 let p1: Vec2 = vec2(4.0, 7.0);
2191 let p2: Vec2 = vec2(13.0, 8.0);
2192 let r = p1.cross(p2);
2193 assert_eq!(r, -59.0);
2194 }
2195
2196 #[test]
2197 pub fn test_normalize() {
2198 use std::f32;
2199
2200 let p0: Vec2 = Vec2::zero();
2201 let p1: Vec2 = vec2(4.0, 0.0);
2202 let p2: Vec2 = vec2(3.0, -4.0);
2203 assert!(p0.normalize().x.is_nan() && p0.normalize().y.is_nan());
2204 assert_eq!(p1.normalize(), vec2(1.0, 0.0));
2205 assert_eq!(p2.normalize(), vec2(0.6, -0.8));
2206
2207 let p3: Vec2 = vec2(::std::f32::MAX, ::std::f32::MAX);
2208 assert_ne!(
2209 p3.normalize(),
2210 vec2(1.0 / 2.0f32.sqrt(), 1.0 / 2.0f32.sqrt())
2211 );
2212 assert_eq!(
2213 p3.robust_normalize(),
2214 vec2(1.0 / 2.0f32.sqrt(), 1.0 / 2.0f32.sqrt())
2215 );
2216
2217 let p4: Vec2 = Vec2::zero();
2218 assert!(p4.try_normalize().is_none());
2219 let p5: Vec2 = Vec2::new(f32::MIN_POSITIVE, f32::MIN_POSITIVE);
2220 assert!(p5.try_normalize().is_none());
2221
2222 let p6: Vec2 = vec2(4.0, 0.0);
2223 let p7: Vec2 = vec2(3.0, -4.0);
2224 assert_eq!(p6.try_normalize().unwrap(), vec2(1.0, 0.0));
2225 assert_eq!(p7.try_normalize().unwrap(), vec2(0.6, -0.8));
2226 }
2227
2228 #[test]
2229 pub fn test_min() {
2230 let p1: Vec2 = vec2(1.0, 3.0);
2231 let p2: Vec2 = vec2(2.0, 2.0);
2232
2233 let result = p1.min(p2);
2234
2235 assert_eq!(result, vec2(1.0, 2.0));
2236 }
2237
2238 #[test]
2239 pub fn test_max() {
2240 let p1: Vec2 = vec2(1.0, 3.0);
2241 let p2: Vec2 = vec2(2.0, 2.0);
2242
2243 let result = p1.max(p2);
2244
2245 assert_eq!(result, vec2(2.0, 3.0));
2246 }
2247
2248 #[test]
2249 pub fn test_angle_from_x_axis() {
2250 use crate::approxeq::ApproxEq;
2251 use core::f32::consts::FRAC_PI_2;
2252
2253 let right: Vec2 = vec2(10.0, 0.0);
2254 let down: Vec2 = vec2(0.0, 4.0);
2255 let up: Vec2 = vec2(0.0, -1.0);
2256
2257 assert!(right.angle_from_x_axis().get().approx_eq(&0.0));
2258 assert!(down.angle_from_x_axis().get().approx_eq(&FRAC_PI_2));
2259 assert!(up.angle_from_x_axis().get().approx_eq(&-FRAC_PI_2));
2260 }
2261
2262 #[test]
2263 pub fn test_angle_to() {
2264 use crate::approxeq::ApproxEq;
2265 use core::f32::consts::FRAC_PI_2;
2266
2267 let right: Vec2 = vec2(10.0, 0.0);
2268 let right2: Vec2 = vec2(1.0, 0.0);
2269 let up: Vec2 = vec2(0.0, -1.0);
2270 let up_left: Vec2 = vec2(-1.0, -1.0);
2271
2272 assert!(right.angle_to(right2).get().approx_eq(&0.0));
2273 assert!(right.angle_to(up).get().approx_eq(&-FRAC_PI_2));
2274 assert!(up.angle_to(right).get().approx_eq(&FRAC_PI_2));
2275 assert!(up_left
2276 .angle_to(up)
2277 .get()
2278 .approx_eq_eps(&(0.5 * FRAC_PI_2), &0.0005));
2279 }
2280
2281 #[test]
2282 pub fn test_with_max_length() {
2283 use crate::approxeq::ApproxEq;
2284
2285 let v1: Vec2 = vec2(0.5, 0.5);
2286 let v2: Vec2 = vec2(1.0, 0.0);
2287 let v3: Vec2 = vec2(0.1, 0.2);
2288 let v4: Vec2 = vec2(2.0, -2.0);
2289 let v5: Vec2 = vec2(1.0, 2.0);
2290 let v6: Vec2 = vec2(-1.0, 3.0);
2291
2292 assert_eq!(v1.with_max_length(1.0), v1);
2293 assert_eq!(v2.with_max_length(1.0), v2);
2294 assert_eq!(v3.with_max_length(1.0), v3);
2295 assert_eq!(v4.with_max_length(10.0), v4);
2296 assert_eq!(v5.with_max_length(10.0), v5);
2297 assert_eq!(v6.with_max_length(10.0), v6);
2298
2299 let v4_clamped = v4.with_max_length(1.0);
2300 assert!(v4_clamped.length().approx_eq(&1.0));
2301 assert!(v4_clamped.normalize().approx_eq(&v4.normalize()));
2302
2303 let v5_clamped = v5.with_max_length(1.5);
2304 assert!(v5_clamped.length().approx_eq(&1.5));
2305 assert!(v5_clamped.normalize().approx_eq(&v5.normalize()));
2306
2307 let v6_clamped = v6.with_max_length(2.5);
2308 assert!(v6_clamped.length().approx_eq(&2.5));
2309 assert!(v6_clamped.normalize().approx_eq(&v6.normalize()));
2310 }
2311
2312 #[test]
2313 pub fn test_project_onto_vector() {
2314 use crate::approxeq::ApproxEq;
2315
2316 let v1: Vec2 = vec2(1.0, 2.0);
2317 let x: Vec2 = vec2(1.0, 0.0);
2318 let y: Vec2 = vec2(0.0, 1.0);
2319
2320 assert!(v1.project_onto_vector(x).approx_eq(&vec2(1.0, 0.0)));
2321 assert!(v1.project_onto_vector(y).approx_eq(&vec2(0.0, 2.0)));
2322 assert!(v1.project_onto_vector(-x).approx_eq(&vec2(1.0, 0.0)));
2323 assert!(v1.project_onto_vector(x * 10.0).approx_eq(&vec2(1.0, 0.0)));
2324 assert!(v1.project_onto_vector(v1 * 2.0).approx_eq(&v1));
2325 assert!(v1.project_onto_vector(-v1).approx_eq(&v1));
2326 }
2327
2328 #[cfg(feature = "mint")]
2329 #[test]
2330 pub fn test_mint() {
2331 let v1 = Vec2::new(1.0, 3.0);
2332 let vm: mint::Vector2<_> = v1.into();
2333 let v2 = Vec2::from(vm);
2334
2335 assert_eq!(v1, v2);
2336 }
2337
2338 pub enum Mm {}
2339 pub enum Cm {}
2340
2341 pub type Vector2DMm<T> = super::Vector2D<T, Mm>;
2342 pub type Vector2DCm<T> = super::Vector2D<T, Cm>;
2343
2344 #[test]
2345 pub fn test_add() {
2346 let p1 = Vector2DMm::new(1.0, 2.0);
2347 let p2 = Vector2DMm::new(3.0, 4.0);
2348
2349 assert_eq!(p1 + p2, vec2(4.0, 6.0));
2350 assert_eq!(p1 + &p2, vec2(4.0, 6.0));
2351 }
2352
2353 #[test]
2354 pub fn test_sum() {
2355 let vecs = [
2356 Vector2DMm::new(1.0, 2.0),
2357 Vector2DMm::new(3.0, 4.0),
2358 Vector2DMm::new(5.0, 6.0),
2359 ];
2360 let sum = Vector2DMm::new(9.0, 12.0);
2361 assert_eq!(vecs.iter().sum::<Vector2DMm<_>>(), sum);
2362 }
2363
2364 #[test]
2365 pub fn test_add_assign() {
2366 let mut p1 = Vector2DMm::new(1.0, 2.0);
2367 p1 += vec2(3.0, 4.0);
2368
2369 assert_eq!(p1, vec2(4.0, 6.0));
2370 }
2371
2372 #[test]
2373 pub fn test_typed_scalar_mul() {
2374 let p1 = Vector2DMm::new(1.0, 2.0);
2375 let cm_per_mm = Scale::<f32, Mm, Cm>::new(0.1);
2376
2377 let result: Vector2DCm<f32> = p1 * cm_per_mm;
2378
2379 assert_eq!(result, vec2(0.1, 0.2));
2380 }
2381
2382 #[test]
2383 pub fn test_swizzling() {
2384 let p: default::Vector2D<i32> = vec2(1, 2);
2385 assert_eq!(p.yx(), vec2(2, 1));
2386 }
2387
2388 #[test]
2389 pub fn test_reflect() {
2390 use crate::approxeq::ApproxEq;
2391 let a: Vec2 = vec2(1.0, 3.0);
2392 let n1: Vec2 = vec2(0.0, -1.0);
2393 let n2: Vec2 = vec2(1.0, -1.0).normalize();
2394
2395 assert!(a.reflect(n1).approx_eq(&vec2(1.0, -3.0)));
2396 assert!(a.reflect(n2).approx_eq(&vec2(3.0, 1.0)));
2397 }
2398}
2399
2400#[cfg(test)]
2401mod vector3d {
2402 use crate::scale::Scale;
2403 use crate::{default, vec2, vec3};
2404 #[cfg(feature = "mint")]
2405 use mint;
2406
2407 type Vec3 = default::Vector3D<f32>;
2408
2409 #[test]
2410 pub fn test_add() {
2411 let p1 = Vec3::new(1.0, 2.0, 3.0);
2412 let p2 = Vec3::new(4.0, 5.0, 6.0);
2413
2414 assert_eq!(p1 + p2, vec3(5.0, 7.0, 9.0));
2415 assert_eq!(p1 + &p2, vec3(5.0, 7.0, 9.0));
2416 }
2417
2418 #[test]
2419 pub fn test_sum() {
2420 let vecs = [
2421 Vec3::new(1.0, 2.0, 3.0),
2422 Vec3::new(4.0, 5.0, 6.0),
2423 Vec3::new(7.0, 8.0, 9.0),
2424 ];
2425 let sum = Vec3::new(12.0, 15.0, 18.0);
2426 assert_eq!(vecs.iter().sum::<Vec3>(), sum);
2427 }
2428
2429 #[test]
2430 pub fn test_dot() {
2431 let p1: Vec3 = vec3(7.0, 21.0, 32.0);
2432 let p2: Vec3 = vec3(43.0, 5.0, 16.0);
2433 assert_eq!(p1.dot(p2), 918.0);
2434 }
2435
2436 #[test]
2437 pub fn test_cross() {
2438 let p1: Vec3 = vec3(4.0, 7.0, 9.0);
2439 let p2: Vec3 = vec3(13.0, 8.0, 3.0);
2440 let p3 = p1.cross(p2);
2441 assert_eq!(p3, vec3(-51.0, 105.0, -59.0));
2442 }
2443
2444 #[test]
2445 pub fn test_normalize() {
2446 use std::f32;
2447
2448 let p0: Vec3 = Vec3::zero();
2449 let p1: Vec3 = vec3(0.0, -6.0, 0.0);
2450 let p2: Vec3 = vec3(1.0, 2.0, -2.0);
2451 assert!(
2452 p0.normalize().x.is_nan() && p0.normalize().y.is_nan() && p0.normalize().z.is_nan()
2453 );
2454 assert_eq!(p1.normalize(), vec3(0.0, -1.0, 0.0));
2455 assert_eq!(p2.normalize(), vec3(1.0 / 3.0, 2.0 / 3.0, -2.0 / 3.0));
2456
2457 let p3: Vec3 = vec3(::std::f32::MAX, ::std::f32::MAX, 0.0);
2458 assert_ne!(
2459 p3.normalize(),
2460 vec3(1.0 / 2.0f32.sqrt(), 1.0 / 2.0f32.sqrt(), 0.0)
2461 );
2462 assert_eq!(
2463 p3.robust_normalize(),
2464 vec3(1.0 / 2.0f32.sqrt(), 1.0 / 2.0f32.sqrt(), 0.0)
2465 );
2466
2467 let p4: Vec3 = Vec3::zero();
2468 assert!(p4.try_normalize().is_none());
2469 let p5: Vec3 = Vec3::new(f32::MIN_POSITIVE, f32::MIN_POSITIVE, f32::MIN_POSITIVE);
2470 assert!(p5.try_normalize().is_none());
2471
2472 let p6: Vec3 = vec3(4.0, 0.0, 3.0);
2473 let p7: Vec3 = vec3(3.0, -4.0, 0.0);
2474 assert_eq!(p6.try_normalize().unwrap(), vec3(0.8, 0.0, 0.6));
2475 assert_eq!(p7.try_normalize().unwrap(), vec3(0.6, -0.8, 0.0));
2476 }
2477
2478 #[test]
2479 pub fn test_min() {
2480 let p1: Vec3 = vec3(1.0, 3.0, 5.0);
2481 let p2: Vec3 = vec3(2.0, 2.0, -1.0);
2482
2483 let result = p1.min(p2);
2484
2485 assert_eq!(result, vec3(1.0, 2.0, -1.0));
2486 }
2487
2488 #[test]
2489 pub fn test_max() {
2490 let p1: Vec3 = vec3(1.0, 3.0, 5.0);
2491 let p2: Vec3 = vec3(2.0, 2.0, -1.0);
2492
2493 let result = p1.max(p2);
2494
2495 assert_eq!(result, vec3(2.0, 3.0, 5.0));
2496 }
2497
2498 #[test]
2499 pub fn test_clamp() {
2500 let p1: Vec3 = vec3(1.0, -1.0, 5.0);
2501 let p2: Vec3 = vec3(2.0, 5.0, 10.0);
2502 let p3: Vec3 = vec3(-1.0, 2.0, 20.0);
2503
2504 let result = p3.clamp(p1, p2);
2505
2506 assert_eq!(result, vec3(1.0, 2.0, 10.0));
2507 }
2508
2509 #[test]
2510 pub fn test_typed_scalar_mul() {
2511 enum Mm {}
2512 enum Cm {}
2513
2514 let p1 = super::Vector3D::<f32, Mm>::new(1.0, 2.0, 3.0);
2515 let cm_per_mm = Scale::<f32, Mm, Cm>::new(0.1);
2516
2517 let result: super::Vector3D<f32, Cm> = p1 * cm_per_mm;
2518
2519 assert_eq!(result, vec3(0.1, 0.2, 0.3));
2520 }
2521
2522 #[test]
2523 pub fn test_swizzling() {
2524 let p: Vec3 = vec3(1.0, 2.0, 3.0);
2525 assert_eq!(p.xy(), vec2(1.0, 2.0));
2526 assert_eq!(p.xz(), vec2(1.0, 3.0));
2527 assert_eq!(p.yz(), vec2(2.0, 3.0));
2528 }
2529
2530 #[cfg(feature = "mint")]
2531 #[test]
2532 pub fn test_mint() {
2533 let v1 = Vec3::new(1.0, 3.0, 5.0);
2534 let vm: mint::Vector3<_> = v1.into();
2535 let v2 = Vec3::from(vm);
2536
2537 assert_eq!(v1, v2);
2538 }
2539
2540 #[test]
2541 pub fn test_reflect() {
2542 use crate::approxeq::ApproxEq;
2543 let a: Vec3 = vec3(1.0, 3.0, 2.0);
2544 let n1: Vec3 = vec3(0.0, -1.0, 0.0);
2545 let n2: Vec3 = vec3(0.0, 1.0, 1.0).normalize();
2546
2547 assert!(a.reflect(n1).approx_eq(&vec3(1.0, -3.0, 2.0)));
2548 assert!(a.reflect(n2).approx_eq(&vec3(1.0, -2.0, -3.0)));
2549 }
2550
2551 #[test]
2552 pub fn test_angle_to() {
2553 use crate::approxeq::ApproxEq;
2554 use core::f32::consts::FRAC_PI_2;
2555
2556 let right: Vec3 = vec3(10.0, 0.0, 0.0);
2557 let right2: Vec3 = vec3(1.0, 0.0, 0.0);
2558 let up: Vec3 = vec3(0.0, -1.0, 0.0);
2559 let up_left: Vec3 = vec3(-1.0, -1.0, 0.0);
2560
2561 assert!(right.angle_to(right2).get().approx_eq(&0.0));
2562 assert!(right.angle_to(up).get().approx_eq(&FRAC_PI_2));
2563 assert!(up.angle_to(right).get().approx_eq(&FRAC_PI_2));
2564 assert!(up_left
2565 .angle_to(up)
2566 .get()
2567 .approx_eq_eps(&(0.5 * FRAC_PI_2), &0.0005));
2568 }
2569
2570 #[test]
2571 pub fn test_with_max_length() {
2572 use crate::approxeq::ApproxEq;
2573
2574 let v1: Vec3 = vec3(0.5, 0.5, 0.0);
2575 let v2: Vec3 = vec3(1.0, 0.0, 0.0);
2576 let v3: Vec3 = vec3(0.1, 0.2, 0.3);
2577 let v4: Vec3 = vec3(2.0, -2.0, 2.0);
2578 let v5: Vec3 = vec3(1.0, 2.0, -3.0);
2579 let v6: Vec3 = vec3(-1.0, 3.0, 2.0);
2580
2581 assert_eq!(v1.with_max_length(1.0), v1);
2582 assert_eq!(v2.with_max_length(1.0), v2);
2583 assert_eq!(v3.with_max_length(1.0), v3);
2584 assert_eq!(v4.with_max_length(10.0), v4);
2585 assert_eq!(v5.with_max_length(10.0), v5);
2586 assert_eq!(v6.with_max_length(10.0), v6);
2587
2588 let v4_clamped = v4.with_max_length(1.0);
2589 assert!(v4_clamped.length().approx_eq(&1.0));
2590 assert!(v4_clamped.normalize().approx_eq(&v4.normalize()));
2591
2592 let v5_clamped = v5.with_max_length(1.5);
2593 assert!(v5_clamped.length().approx_eq(&1.5));
2594 assert!(v5_clamped.normalize().approx_eq(&v5.normalize()));
2595
2596 let v6_clamped = v6.with_max_length(2.5);
2597 assert!(v6_clamped.length().approx_eq(&2.5));
2598 assert!(v6_clamped.normalize().approx_eq(&v6.normalize()));
2599 }
2600
2601 #[test]
2602 pub fn test_project_onto_vector() {
2603 use crate::approxeq::ApproxEq;
2604
2605 let v1: Vec3 = vec3(1.0, 2.0, 3.0);
2606 let x: Vec3 = vec3(1.0, 0.0, 0.0);
2607 let y: Vec3 = vec3(0.0, 1.0, 0.0);
2608 let z: Vec3 = vec3(0.0, 0.0, 1.0);
2609
2610 assert!(v1.project_onto_vector(x).approx_eq(&vec3(1.0, 0.0, 0.0)));
2611 assert!(v1.project_onto_vector(y).approx_eq(&vec3(0.0, 2.0, 0.0)));
2612 assert!(v1.project_onto_vector(z).approx_eq(&vec3(0.0, 0.0, 3.0)));
2613 assert!(v1.project_onto_vector(-x).approx_eq(&vec3(1.0, 0.0, 0.0)));
2614 assert!(v1
2615 .project_onto_vector(x * 10.0)
2616 .approx_eq(&vec3(1.0, 0.0, 0.0)));
2617 assert!(v1.project_onto_vector(v1 * 2.0).approx_eq(&v1));
2618 assert!(v1.project_onto_vector(-v1).approx_eq(&v1));
2619 }
2620}
2621
2622#[cfg(test)]
2623mod bool_vector {
2624 use super::*;
2625 use crate::default;
2626 type Vec2 = default::Vector2D<f32>;
2627 type Vec3 = default::Vector3D<f32>;
2628
2629 #[test]
2630 fn test_bvec2() {
2631 assert_eq!(
2632 Vec2::new(1.0, 2.0).greater_than(Vec2::new(2.0, 1.0)),
2633 bvec2(false, true),
2634 );
2635
2636 assert_eq!(
2637 Vec2::new(1.0, 2.0).lower_than(Vec2::new(2.0, 1.0)),
2638 bvec2(true, false),
2639 );
2640
2641 assert_eq!(
2642 Vec2::new(1.0, 2.0).equal(Vec2::new(1.0, 3.0)),
2643 bvec2(true, false),
2644 );
2645
2646 assert_eq!(
2647 Vec2::new(1.0, 2.0).not_equal(Vec2::new(1.0, 3.0)),
2648 bvec2(false, true),
2649 );
2650
2651 assert!(bvec2(true, true).any());
2652 assert!(bvec2(false, true).any());
2653 assert!(bvec2(true, false).any());
2654 assert!(!bvec2(false, false).any());
2655 assert!(bvec2(false, false).none());
2656 assert!(bvec2(true, true).all());
2657 assert!(!bvec2(false, true).all());
2658 assert!(!bvec2(true, false).all());
2659 assert!(!bvec2(false, false).all());
2660
2661 assert_eq!(bvec2(true, false).not(), bvec2(false, true));
2662 assert_eq!(
2663 bvec2(true, false).and(bvec2(true, true)),
2664 bvec2(true, false)
2665 );
2666 assert_eq!(bvec2(true, false).or(bvec2(true, true)), bvec2(true, true));
2667
2668 assert_eq!(
2669 bvec2(true, false).select_vector(Vec2::new(1.0, 2.0), Vec2::new(3.0, 4.0)),
2670 Vec2::new(1.0, 4.0),
2671 );
2672 }
2673
2674 #[test]
2675 fn test_bvec3() {
2676 assert_eq!(
2677 Vec3::new(1.0, 2.0, 3.0).greater_than(Vec3::new(3.0, 2.0, 1.0)),
2678 bvec3(false, false, true),
2679 );
2680
2681 assert_eq!(
2682 Vec3::new(1.0, 2.0, 3.0).lower_than(Vec3::new(3.0, 2.0, 1.0)),
2683 bvec3(true, false, false),
2684 );
2685
2686 assert_eq!(
2687 Vec3::new(1.0, 2.0, 3.0).equal(Vec3::new(3.0, 2.0, 1.0)),
2688 bvec3(false, true, false),
2689 );
2690
2691 assert_eq!(
2692 Vec3::new(1.0, 2.0, 3.0).not_equal(Vec3::new(3.0, 2.0, 1.0)),
2693 bvec3(true, false, true),
2694 );
2695
2696 assert!(bvec3(true, true, false).any());
2697 assert!(bvec3(false, true, false).any());
2698 assert!(bvec3(true, false, false).any());
2699 assert!(!bvec3(false, false, false).any());
2700 assert!(bvec3(false, false, false).none());
2701 assert!(bvec3(true, true, true).all());
2702 assert!(!bvec3(false, true, false).all());
2703 assert!(!bvec3(true, false, false).all());
2704 assert!(!bvec3(false, false, false).all());
2705
2706 assert_eq!(bvec3(true, false, true).not(), bvec3(false, true, false));
2707 assert_eq!(
2708 bvec3(true, false, true).and(bvec3(true, true, false)),
2709 bvec3(true, false, false)
2710 );
2711 assert_eq!(
2712 bvec3(true, false, false).or(bvec3(true, true, false)),
2713 bvec3(true, true, false)
2714 );
2715
2716 assert_eq!(
2717 bvec3(true, false, true)
2718 .select_vector(Vec3::new(1.0, 2.0, 3.0), Vec3::new(4.0, 5.0, 6.0)),
2719 Vec3::new(1.0, 5.0, 3.0),
2720 );
2721 }
2722}