1use core::{
6 array,
7 fmt::{Debug, Formatter},
8 iter::Sum,
9 marker::PhantomData as Pd,
10 ops::{Add, Div, Index, IndexMut, Mul, Neg, Sub},
11 ops::{AddAssign, DivAssign, MulAssign, SubAssign},
12};
13
14use crate::math::{
15 Affine, ApproxEq, Linear, Point,
16 space::{Proj3, Real},
17 vary::ZDiv,
18};
19
20#[repr(transparent)]
37pub struct Vector<Repr, Space = ()>(pub Repr, Pd<Space>);
38
39pub type Vec2<Basis = ()> = Vector<[f32; 2], Real<2, Basis>>;
41pub type Vec3<Basis = ()> = Vector<[f32; 3], Real<3, Basis>>;
43pub type ProjVec3 = Vector<[f32; 4], Proj3>;
45
46pub type Vec2i<Basis = ()> = Vector<[i32; 2], Real<2, Basis>>;
51pub type Vec3i<Basis = ()> = Vector<[i32; 3], Real<3, Basis>>;
53
54pub const fn vec2<Sc, B>(x: Sc, y: Sc) -> Vector<[Sc; 2], Real<2, B>> {
60 Vector([x, y], Pd)
61}
62
63pub const fn vec3<Sc, B>(x: Sc, y: Sc, z: Sc) -> Vector<[Sc; 3], Real<3, B>> {
65 Vector([x, y, z], Pd)
66}
67
68#[inline]
78pub fn splat<Sp, Sc: Clone, const DIM: usize>(s: Sc) -> Vector<[Sc; DIM], Sp> {
79 array::from_fn(|_| s.clone()).into() }
81
82impl<R, Sp> Vector<R, Sp> {
87 #[inline]
89 pub const fn new(repr: R) -> Self {
90 Self(repr, Pd)
91 }
92
93 #[inline]
101 pub fn to<S>(self) -> Vector<R, S> {
102 Vector::new(self.0)
103 }
104
105 #[inline]
108 pub fn to_pt(self) -> Point<R, Sp> {
109 Point::new(self.0)
110 }
111}
112
113impl<Sp, const N: usize> Vector<[f32; N], Sp> {
115 #[cfg(feature = "fp")]
117 #[inline]
118 pub fn len(&self) -> f32 {
119 super::float::f32::sqrt(self.dot(self))
120 }
121
122 #[inline]
137 #[must_use]
138 pub fn normalize(&self) -> Self {
139 #[cfg(feature = "std")]
140 use super::float::RecipSqrt;
141 use super::float::f32;
142 let len_sqr = self.len_sqr();
143 assert!(
144 len_sqr.is_finite() && !len_sqr.approx_eq_eps(&0.0, &1e-12),
145 "cannot normalize a near-zero or non-finite vector: {:?}",
146 self.0
147 );
148 *self * f32::recip_sqrt(len_sqr)
149 }
150
151 #[must_use]
169 pub fn clamp(&self, min: &Self, max: &Self) -> Self {
170 array::from_fn(|i| self[i].clamp(min[i], max[i])).into()
171 }
172
173 pub fn is_finite(&self) -> bool {
178 self.0.iter().all(|c| c.is_finite())
179 }
180}
181
182impl<Sc, Sp, const N: usize> Vector<[Sc; N], Sp>
183where
184 Self: Linear<Scalar = Sc>,
185 Sc: Linear<Scalar = Sc> + Copy,
186{
187 #[inline]
192 pub fn len_sqr(&self) -> Sc {
193 self.dot(self)
194 }
195
196 #[inline]
198 pub fn dot(&self, other: &Self) -> Sc {
199 self.0
200 .iter()
201 .zip(&other.0)
202 .map(|(a, b)| a.mul(*b))
203 .fold(Sc::zero(), |acc, x| acc.add(&x))
204 }
205
206 #[must_use]
209 pub fn scalar_project(&self, other: &Self) -> Sc
210 where
211 Sc: Div<Sc, Output = Sc>,
212 {
213 self.dot(other) / other.dot(other)
214 }
215 #[must_use]
229 pub fn vector_project(&self, other: &Self) -> Self
230 where
231 Sc: Div<Sc, Output = Sc>,
232 {
233 other.mul(self.scalar_project(other))
234 }
235
236 pub fn reflect(self, other: Self) -> Self
248 where
249 Sc: Div<Sc, Output = Sc>,
250 {
251 let proj_on_other = self.vector_project(&other);
252 proj_on_other + proj_on_other - self
253 }
254}
255
256impl<Sc: Copy, Sp, const N: usize> Vector<[Sc; N], Sp> {
257 #[inline]
268 #[must_use]
269 pub fn map<T>(self, mut f: impl FnMut(Sc) -> T) -> Vector<[T; N], Sp> {
270 array::from_fn(|i| f(self.0[i])).into()
271 }
272 #[inline]
284 #[must_use]
285 pub fn zip_map<T: Copy, U>(
286 self,
287 other: Vector<[T; N], Sp>,
288 mut f: impl FnMut(Sc, T) -> U,
289 ) -> Vector<[U; N], Sp> {
290 array::from_fn(|i| f(self.0[i], other.0[i])).into()
291 }
292}
293
294impl<R, Sc, B> Vector<R, Real<2, B>>
295where
296 R: Index<usize, Output = Sc>,
297 Sc: Copy,
298{
299 #[inline]
301 pub fn x(&self) -> Sc {
302 self.0[0]
303 }
304 #[inline]
306 pub fn y(&self) -> Sc {
307 self.0[1]
308 }
309}
310
311impl<B> Vec2<B> {
313 pub const X: Self = vec2(1.0, 0.0);
315
316 pub const Y: Self = vec2(0.0, 1.0);
318
319 pub fn to_vec3(self) -> Vec3<B> {
321 vec3(self.x(), self.y(), 0.0)
322 }
323
324 #[inline]
334 pub fn perp(self) -> Self {
335 vec2(-self.y(), self.x())
336 }
337
338 #[inline]
371 pub fn perp_dot(self, other: Self) -> f32 {
372 self.perp().dot(&other)
373 }
374}
375
376impl<R, Sc, B> Vector<R, Real<3, B>>
377where
378 R: Index<usize, Output = Sc>,
379 Sc: Copy,
380{
381 #[inline]
383 pub fn x(&self) -> Sc {
384 self.0[0]
385 }
386 #[inline]
388 pub fn y(&self) -> Sc {
389 self.0[1]
390 }
391 #[inline]
393 pub fn z(&self) -> Sc {
394 self.0[2]
395 }
396
397 pub fn cross(&self, other: &Self) -> Self
424 where
425 Sc: Linear<Scalar = Sc>,
426 [Sc; 3]: Into<Self>,
427 {
428 let (s, o) = (self, other);
429 [
430 s.y().mul(o.z()).sub(&s.z().mul(o.y())),
431 s.z().mul(o.x()).sub(&s.x().mul(o.z())),
432 s.x().mul(o.y()).sub(&s.y().mul(o.x())),
433 ]
434 .into()
435 }
436}
437
438impl<B> Vec3<B> {
440 pub const X: Self = vec3(1.0, 0.0, 0.0);
442
443 pub const Y: Self = vec3(0.0, 1.0, 0.0);
445
446 pub const Z: Self = vec3(0.0, 0.0, 1.0);
448}
449
450impl<R, Sc> Vector<R, Proj3>
451where
452 R: Index<usize, Output = Sc>,
453 Sc: Copy,
454{
455 #[inline]
457 pub fn x(&self) -> Sc {
458 self.0[0]
459 }
460 #[inline]
462 pub fn y(&self) -> Sc {
463 self.0[1]
464 }
465 #[inline]
467 pub fn z(&self) -> Sc {
468 self.0[2]
469 }
470 #[inline]
472 pub fn w(&self) -> Sc {
473 self.0[3]
474 }
475}
476
477impl<Sc, Sp, const DIM: usize> Affine for Vector<[Sc; DIM], Sp>
482where
483 Sc: Linear<Scalar = Sc> + Copy,
484{
485 type Space = Sp;
486 type Diff = Self;
487
488 const DIM: usize = DIM;
490
491 #[inline]
492 fn add(&self, other: &Self) -> Self {
493 Self(array::from_fn(|i| self.0[i].add(&other.0[i])), Pd)
495 }
496 #[inline]
497 fn sub(&self, other: &Self) -> Self {
498 Self(array::from_fn(|i| self.0[i].sub(&other.0[i])), Pd)
499 }
500}
501
502impl<Sc, Sp, const DIM: usize> Linear for Vector<[Sc; DIM], Sp>
503where
504 Sc: Linear<Scalar = Sc> + Copy,
505{
506 type Scalar = Sc;
507
508 #[inline]
510 fn zero() -> Self {
511 Self([Sc::zero(); DIM], Pd)
512 }
513 #[inline]
514 fn mul(&self, scalar: Sc) -> Self {
515 self.map(|c| c.mul(scalar))
516 }
517}
518
519impl<Sc, Sp, const N: usize> ZDiv for Vector<[Sc; N], Sp>
520where
521 Sc: ZDiv + Copy,
522{
523 fn z_div(self, z: f32) -> Self {
524 self.map(|c| c.z_div(z))
525 }
526}
527
528impl<Sc: ApproxEq, Sp, const N: usize> ApproxEq<Self, Sc>
529 for Vector<[Sc; N], Sp>
530{
531 fn approx_eq_eps(&self, other: &Self, eps: &Sc) -> bool {
532 self.0.approx_eq_eps(&other.0, eps)
533 }
534 fn relative_epsilon() -> Sc {
535 Sc::relative_epsilon()
536 }
537}
538
539impl<R: Copy, S> Copy for Vector<R, S> {}
547
548impl<R: Clone, S> Clone for Vector<R, S> {
549 fn clone(&self) -> Self {
550 Self(self.0.clone(), Pd)
551 }
552}
553
554impl<R: Default, B, const DIM: usize> Default for Vector<R, Real<DIM, B>> {
555 fn default() -> Self {
556 Self(R::default(), Pd)
557 }
558}
559
560impl<R: Eq, S> Eq for Vector<R, S> {}
561
562impl<R: PartialEq, S> PartialEq for Vector<R, S> {
563 fn eq(&self, other: &Self) -> bool {
564 self.0 == other.0
565 }
566}
567
568impl<R: Debug, Sp: Debug + Default> Debug for Vector<R, Sp> {
569 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
570 write!(f, "Vec<{:?}>", Sp::default())?;
571 Debug::fmt(&self.0, f)
572 }
573}
574
575impl<R, Sp> From<R> for Vector<R, Sp> {
576 #[inline]
577 fn from(repr: R) -> Self {
578 Self(repr, Pd)
579 }
580}
581
582impl<Sp, Sc: Clone, const DIM: usize> From<Sc> for Vector<[Sc; DIM], Sp> {
583 #[inline]
587 fn from(scalar: Sc) -> Self {
588 splat(scalar)
589 }
590}
591impl<R, Sp> Index<usize> for Vector<R, Sp>
606where
607 Self: Affine,
608 R: Index<usize>,
609{
610 type Output = R::Output;
611
612 #[inline]
618 fn index(&self, i: usize) -> &Self::Output {
619 assert!(i < Self::DIM, "index {i} out of bounds ({})", Self::DIM);
620 &self.0[i]
621 }
622}
623
624impl<R, Sp> IndexMut<usize> for Vector<R, Sp>
625where
626 Self: Affine,
627 R: IndexMut<usize>,
628{
629 #[inline]
635 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
636 assert!(i < Self::DIM, "index {i} out of bounds ({})", Self::DIM);
637 &mut self.0[i]
638 }
639}
640
641impl<R, Sp> Sum for Vector<R, Sp>
642where
643 Self: Linear,
644{
645 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
646 iter.fold(Self::zero(), |acc, v| Affine::add(&acc, &v))
647 }
648}
649
650impl<R, Sp> AddAssign<<Self as Affine>::Diff> for Vector<R, Sp>
656where
657 Self: Affine,
658{
659 #[inline]
660 fn add_assign(&mut self, rhs: <Self as Affine>::Diff) {
661 *self = Affine::add(&*self, &rhs);
662 }
663}
664
665impl<R, Sp> SubAssign<<Self as Affine>::Diff> for Vector<R, Sp>
667where
668 Self: Affine,
669{
670 #[inline]
671 fn sub_assign(&mut self, rhs: <Self as Affine>::Diff) {
672 *self = Affine::add(&*self, &rhs.neg());
673 }
674}
675
676impl<R, Sp> MulAssign<<Self as Linear>::Scalar> for Vector<R, Sp>
678where
679 Self: Linear,
680{
681 #[inline]
682 fn mul_assign(&mut self, rhs: <Self as Linear>::Scalar) {
683 *self = Linear::mul(&*self, rhs);
684 }
685}
686
687impl<R, Sp> DivAssign<f32> for Vector<R, Sp>
689where
690 Self: Linear<Scalar = f32>,
691{
692 #[inline]
693 fn div_assign(&mut self, rhs: f32) {
694 debug_assert!(!rhs.approx_eq(&0.0), "divisor {rhs} < epsilon");
695 *self = Linear::mul(&*self, rhs.recip());
696 }
697}
698
699impl<R, Sp> Neg for Vector<R, Sp>
701where
702 Self: Linear,
703{
704 type Output = Self;
705
706 #[inline]
707 fn neg(self) -> Self::Output {
708 <Self as Linear>::neg(&self)
709 }
710}
711
712impl<R, Sp> Mul<Vector<R, Sp>> for f32
713where
714 Vector<R, Sp>: Linear<Scalar = f32>,
715{
716 type Output = Vector<R, Sp>;
717
718 #[inline]
719 fn mul(self, rhs: Vector<R, Sp>) -> Self::Output {
720 rhs * self
721 }
722}
723impl<R, Sp> Mul<Vector<R, Sp>> for i32
724where
725 Vector<R, Sp>: Linear<Scalar = i32>,
726{
727 type Output = Vector<R, Sp>;
728
729 #[inline]
730 fn mul(self, rhs: Vector<R, Sp>) -> Self::Output {
731 rhs * self
732 }
733}
734impl<R, Sp> Mul<Vector<R, Sp>> for u32
735where
736 Vector<R, Sp>: Linear<Scalar = u32>,
737{
738 type Output = Vector<R, Sp>;
739
740 #[inline]
741 fn mul(self, rhs: Vector<R, Sp>) -> Self::Output {
742 rhs * self
743 }
744}
745
746impl_op!(Add::add, Vector, <Self as Affine>::Diff, +=, bound=Affine);
748impl_op!(Sub::sub, Vector, <Self as Affine>::Diff, -=, bound=Affine);
750impl_op!(Mul::mul, Vector, <Self as Linear>::Scalar, *=);
752impl_op!(Div::div, Vector, f32, /=, bound=Linear<Scalar = f32>);
754
755#[cfg(test)]
760mod tests {
761 use core::f32::consts::*;
762
763 use crate::assert_approx_eq;
764
765 use super::*;
766
767 pub const fn vec2<S>(x: S, y: S) -> Vector<[S; 2], Real<2>> {
768 super::vec2(x, y)
769 }
770 pub const fn vec3<S>(x: S, y: S, z: S) -> Vector<[S; 3], Real<3>> {
771 super::vec3(x, y, z)
772 }
773 pub const fn vec4<S>(x: S, y: S, z: S, w: S) -> Vector<[S; 4], Real<4>> {
774 Vector::new([x, y, z, w])
775 }
776
777 mod f32 {
778 use super::*;
779
780 #[cfg(feature = "fp")]
781 #[test]
782 fn length() {
783 assert_approx_eq!(vec2(1.0, 1.0).len(), SQRT_2);
784 assert_approx_eq!(vec2(-3.0, 4.0).len(), 5.0);
785 assert_approx_eq!(vec3(1.0, -2.0, 3.0).len(), 14.0f32.sqrt());
786 }
787
788 #[test]
789 fn length_squared() {
790 assert_eq!(vec2(1.0, 1.0).len_sqr(), 2.0);
791 assert_eq!(vec2(-4.0, 3.0).len_sqr(), 25.0);
792 assert_eq!(vec3(1.0, -2.0, 3.0).len_sqr(), 14.0);
793 }
794
795 #[test]
796 fn normalize() {
797 assert_approx_eq!(vec2(3.0, 4.0).normalize(), vec2(0.6, 0.8));
798
799 let sqrt_14 = 14.0f32.sqrt();
800 assert_approx_eq!(
801 vec3(1.0, 2.0, 3.0).normalize(),
802 vec3(1.0 / sqrt_14, 2.0 / sqrt_14, 3.0 / sqrt_14)
803 );
804 }
805
806 #[test]
807 fn vector_addition() {
808 assert_eq!(vec2(1.0, 2.0) + vec2(-2.0, 1.0), vec2(-1.0, 3.0));
809 assert_eq!(
810 vec3(1.0, 2.0, 0.0) + vec3(-2.0, 1.0, -1.0),
811 vec3(-1.0, 3.0, -1.0)
812 );
813 }
814
815 #[test]
816 fn scalar_multiplication() {
817 assert_eq!(vec2(1.0, -2.0) * 0.0, vec2(0.0, 0.0));
818 assert_eq!(vec3(1.0, -2.0, 3.0) * 3.0, vec3(3.0, -6.0, 9.0));
819 assert_eq!(3.0 * vec3(1.0, -2.0, 3.0), vec3(3.0, -6.0, 9.0));
820 assert_eq!(
821 vec4(1.0, -2.0, 0.0, -3.0) * 3.0,
822 vec4(3.0, -6.0, 0.0, -9.0)
823 );
824 assert_eq!(
825 3.0 * vec4(1.0, -2.0, 0.0, -3.0),
826 vec4(3.0, -6.0, 0.0, -9.0)
827 );
828 }
829
830 #[test]
831 fn scalar_division() {
832 assert_eq!(vec2(1.0, -2.0) / 1.0, vec2(1.0, -2.0));
833 assert_eq!(vec3(3.0, -6.0, 9.0) / 3.0, vec3(1.0, -2.0, 3.0));
834 assert_eq!(
835 vec4(3.0, -6.0, 0.0, -9.0) / 3.0,
836 vec4(1.0, -2.0, 0.0, -3.0)
837 );
838 }
839
840 #[test]
841 fn dot_product() {
842 assert_eq!(vec2(1.0, -2.0).dot(&vec2(2.0, 3.0)), -4.0);
843 assert_eq!(vec3(1.0, -2.0, 3.0).dot(&vec3(2.0, 3.0, -1.0)), -7.0);
844 }
845
846 #[test]
847 fn indexing() {
848 let mut v = vec2(1.0, 2.0);
849 assert_eq!(v[1], 2.0);
850 v[0] = 3.0;
851 assert_eq!(v.0, [3.0, 2.0]);
852
853 let mut v = vec3(1.0, 2.0, 3.0);
854 assert_eq!(v[1], 2.0);
855 v[2] = 4.0;
856 assert_eq!(v.0, [1.0, 2.0, 4.0]);
857 }
858
859 #[test]
860 fn from_array() {
861 assert_eq!(Vec2::from([1.0, -2.0]), vec2(1.0, -2.0));
862 assert_eq!(Vec3::from([1.0, -2.0, 4.0]), vec3(1.0, -2.0, 4.0));
863 assert_eq!(
864 Vector::from([1.0, -2.0, 4.0, -3.0]),
865 vec4(1.0, -2.0, 4.0, -3.0)
866 );
867 }
868
869 #[test]
870 fn perp() {
871 assert_eq!(Vec2::<()>::zero().perp(), Vec2::zero());
872 assert_eq!(Vec2::<()>::X.perp(), Vec2::Y);
873 assert_eq!(vec2(-0.2, -1.5).perp(), vec2(1.5, -0.2));
874 }
875
876 #[test]
877 fn perp_dot() {
878 const X: Vec2 = Vec2::X;
879 const Y: Vec2 = Vec2::Y;
880
881 assert_eq!(X.perp_dot(X), 0.0);
882 assert_eq!(X.perp_dot(Y), 1.0);
883 assert_eq!((2.0 * Y).perp_dot(3.0 * X), -6.0);
884 }
885 }
886
887 mod i32 {
888 use super::*;
889
890 #[test]
891 fn vector_addition() {
892 assert_eq!(vec2(1, 2) + vec2(-2, 1), vec2(-1, 3));
893 assert_eq!(vec3(1, 2, 0) + vec3(-2, 1, -1), vec3(-1, 3, -1));
894 }
895
896 #[test]
897 fn vector_subtraction() {
898 assert_eq!(vec2(1, 2) - vec2(-2, 3), vec2(3, -1));
899 assert_eq!(vec3(1, 2, 0) - vec3(-2, 1, 2), vec3(3, 1, -2));
900 }
901
902 #[test]
903 #[allow(clippy::erasing_op)]
904 fn scalar_multiplication() {
905 assert_eq!(vec2(1, -2) * 0, vec2(0, 0));
906
907 assert_eq!(vec3(1, -2, 3) * 3, vec3(3, -6, 9));
908 assert_eq!(3 * vec3(1, -2, 3), vec3(3, -6, 9));
909
910 assert_eq!(vec4(1, -2, 0, -3) * 3, vec4(3, -6, 0, -9));
911 assert_eq!(3 * vec4(1, -2, 0, -3), vec4(3, -6, 0, -9));
912 }
913
914 #[test]
915 fn dot_product() {
916 assert_eq!(vec2(1, -2).dot(&vec2(2, 3)), -4);
917 assert_eq!(vec3(1, -2, 3).dot(&vec3(2, 3, -1)), -7);
918 }
919
920 #[test]
921 fn indexing() {
922 let mut v = vec2(1, 2);
923 assert_eq!(v[1], 2);
924 v[0] = 3;
925 assert_eq!(v.0, [3, 2]);
926
927 let mut v = vec3(1, 2, 3);
928 assert_eq!(v[1], 2);
929 v[2] = 4;
930 assert_eq!(v.0, [1, 2, 4]);
931 }
932
933 #[test]
934 fn from_array() {
935 assert_eq!(Vec2i::from([1, -2]), vec2(1, -2));
936 assert_eq!(Vec3i::from([1, -2, 3]), vec3(1, -2, 3));
937 }
938 }
939
940 const X: Vec3 = Vec3::X;
941 const Y: Vec3 = Vec3::Y;
942 const Z: Vec3 = Vec3::Z;
943
944 #[test]
945 fn cross_product_basis_vectors() {
946 assert_eq!(X.cross(&Y), Z);
947 assert_eq!(Y.cross(&X), -Z);
948
949 assert_eq!(Y.cross(&Z), X);
950 assert_eq!(Z.cross(&Y), -X);
951
952 assert_eq!(Z.cross(&X), Y);
953 assert_eq!(X.cross(&Z), -Y);
954 }
955
956 #[test]
957 fn cross_product_parallelogram_area() {
958 let a = 3.0 * Y;
959 let b = 2.0 * X - Y;
960 assert_eq!(a.cross(&b).len_sqr(), 6.0 * 6.0);
961 }
962
963 #[test]
964 fn iterator_sum() {
965 let vs = [vec2(-1.0, 2.0), vec2(0.0, 2.0), vec2(3.0, -1.0)];
966 assert_eq!(vs.into_iter().sum::<Vec2>(), vec2(2.0, 3.0));
967 }
968
969 #[test]
970 fn approx_equal_pass() {
971 assert_approx_eq!(vec2(1.0, -10.0), vec2(1.01, -9.9), eps = 0.011);
972 }
973 #[test]
974 #[should_panic]
975 fn approx_equal_fail() {
976 let eps = 2.0 * f32::relative_epsilon();
977 assert_approx_eq!(vec2(1.0, -10.0), vec2(1.0 + eps, -10.0 - eps));
978 }
979
980 #[test]
983 fn debug() {
984 assert_eq!(
985 alloc::format!("{:?}", vec2(1.0, -E)),
986 "Vec<ℝ²<()>>[1.0, -2.7182817]"
987 );
988 assert_eq!(
989 alloc::format!("{:?}", vec3(1.0, -2.0, 3.0)),
990 "Vec<ℝ³<()>>[1.0, -2.0, 3.0]"
991 );
992 assert_eq!(
993 alloc::format!("{:?}", vec4(1.0, -2.0, PI, -4.0)),
994 "Vec<ℝ⁴<()>>[1.0, -2.0, 3.1415927, -4.0]"
995 );
996 }
997}