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