1#[cfg(test)]
9use core::hash;
10use core::ops::{Add, Div, Mul, Neg, Rem, Sub};
12
13use num_traits::{Num, Signed, Zero};
18
19#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug, Default)]
28pub struct Vector2<T1, T2> {
30 pub x_: T1,
32 pub y_: T2,
34}
35
36impl<T1, T2> Vector2<T1, T2> {
37 #[inline]
59 pub const fn new(x_: T1, y_: T2) -> Self {
60 Vector2 { x_, y_ }
61 }
62}
63
64impl<T1: Clone + Num> Vector2<T1, T1> {
65 #[inline]
85 pub fn dot(&self, other: &Self) -> T1 {
86 self.x_.clone() * other.x_.clone() + self.y_.clone() * other.y_.clone()
87 }
88
89 #[inline]
105 pub fn cross(&self, other: &Self) -> T1 {
106 self.x_.clone() * other.y_.clone() - self.y_.clone() * other.x_.clone()
107 }
108
109 #[inline]
135 pub fn scale(&self, t: T1) -> Self {
136 Self::new(self.x_.clone() * t.clone(), self.y_.clone() * t)
137 }
138
139 #[inline]
161 pub fn unscale(&self, t: T1) -> Self {
162 Self::new(self.x_.clone() / t.clone(), self.y_.clone() / t)
163 }
164}
165
166impl<T1: Clone + Signed> Vector2<T1, T1> {
167 #[inline]
185 pub fn l1_norm(&self) -> T1 {
186 self.x_.abs() + self.y_.abs()
187 }
188}
189
190impl<T1: Clone + PartialOrd> Vector2<T1, T1> {
191 #[inline]
207 pub fn norm_inf(&self) -> T1 {
208 if self.x_ > self.y_ {
209 self.x_.clone()
210 } else {
211 self.y_.clone()
212 }
213 }
214}
215
216macro_rules! forward_xf_xf_binop {
217 (impl $imp:ident, $method:ident) => {
218 impl<'a, 'b, T1: Clone + Num, T2: Clone + Num> $imp<&'b Vector2<T1, T2>>
219 for &'a Vector2<T1, T2>
220 {
221 type Output = Vector2<T1, T2>;
222
223 #[inline]
229 fn $method(self, other: &Vector2<T1, T2>) -> Self::Output {
230 self.clone().$method(other.clone())
231 }
232 }
233 };
234}
235
236macro_rules! forward_xf_val_binop {
237 (impl $imp:ident, $method:ident) => {
238 impl<'a, T1: Clone + Num, T2: Clone + Num> $imp<Vector2<T1, T2>> for &'a Vector2<T1, T2> {
239 type Output = Vector2<T1, T2>;
240
241 #[inline]
242 fn $method(self, other: Vector2<T1, T2>) -> Self::Output {
243 self.clone().$method(other)
244 }
245 }
246 };
247}
248
249macro_rules! forward_val_xf_binop {
250 (impl $imp:ident, $method:ident) => {
251 impl<'a, T1: Clone + Num, T2: Clone + Num> $imp<&'a Vector2<T1, T2>> for Vector2<T1, T2> {
252 type Output = Vector2<T1, T2>;
253
254 #[inline]
255 fn $method(self, other: &Vector2<T1, T2>) -> Self::Output {
256 self.$method(other.clone())
257 }
258 }
259 };
260}
261
262macro_rules! forward_all_binop {
263 (impl $imp:ident, $method:ident) => {
264 forward_xf_xf_binop!(impl $imp, $method);
265 forward_xf_val_binop!(impl $imp, $method);
266 forward_val_xf_binop!(impl $imp, $method);
267 };
268}
269
270forward_all_binop!(impl Add, add);
272
273impl<T1: Clone + Num, T2: Clone + Num> Add<Vector2<T1, T2>> for Vector2<T1, T2> {
275 type Output = Self;
276
277 #[inline]
294 fn add(self, other: Self) -> Self::Output {
295 Self::Output::new(self.x_ + other.x_, self.y_ + other.y_)
296 }
297}
298
299forward_all_binop!(impl Sub, sub);
300
301impl<T1: Clone + Num, T2: Clone + Num> Sub<Vector2<T1, T2>> for Vector2<T1, T2> {
303 type Output = Self;
304
305 #[inline]
322 fn sub(self, other: Self) -> Self::Output {
323 Self::Output::new(self.x_ - other.x_, self.y_ - other.y_)
324 }
325}
326
327mod opassign {
330 use core::ops::{AddAssign, DivAssign, MulAssign, SubAssign};
331
332 use num_traits::NumAssign;
333
334 use crate::Vector2;
335
336 impl<T1: Clone + NumAssign, T2: Clone + NumAssign> AddAssign for Vector2<T1, T2> {
337 fn add_assign(&mut self, other: Self) {
359 self.x_ += other.x_;
360 self.y_ += other.y_;
361 }
362 }
363
364 impl<T1: Clone + NumAssign, T2: Clone + NumAssign> SubAssign for Vector2<T1, T2> {
365 fn sub_assign(&mut self, other: Self) {
385 self.x_ -= other.x_;
386 self.y_ -= other.y_;
387 }
388 }
389
390 impl<T1: Clone + NumAssign> MulAssign<T1> for Vector2<T1, T1> {
391 fn mul_assign(&mut self, other: T1) {
409 self.x_ *= other.clone();
410 self.y_ *= other;
411 }
412 }
413
414 impl<T1: Clone + NumAssign> DivAssign<T1> for Vector2<T1, T1> {
415 fn div_assign(&mut self, other: T1) {
433 self.x_ /= other.clone();
434 self.y_ /= other;
435 }
436 }
437
438 macro_rules! forward_op_assign1 {
439 (impl $imp:ident, $method:ident) => {
440 impl<'a, T1: Clone + NumAssign, T2: Clone + NumAssign> $imp<&'a Vector2<T1, T2>>
441 for Vector2<T1, T2>
442 {
443 #[inline]
444 fn $method(&mut self, other: &Self) {
445 self.$method(other.clone())
446 }
447 }
448 };
449 }
450
451 macro_rules! forward_op_assign2 {
452 (impl $imp:ident, $method:ident) => {
453 impl<'a, T1: Clone + NumAssign> $imp<&'a T1> for Vector2<T1, T1> {
454 #[inline]
455 fn $method(&mut self, other: &T1) {
456 self.$method(other.clone())
457 }
458 }
459 };
460 }
461
462 forward_op_assign1!(impl AddAssign, add_assign);
463 forward_op_assign1!(impl SubAssign, sub_assign);
464 forward_op_assign2!(impl MulAssign, mul_assign);
465 forward_op_assign2!(impl DivAssign, div_assign);
466}
467
468impl<T1: Clone + Num + Neg<Output = T1>, T2: Clone + Num + Neg<Output = T2>> Neg
469 for Vector2<T1, T2>
470{
471 type Output = Self;
472
473 #[inline]
486 fn neg(self) -> Self::Output {
487 Self::Output::new(-self.x_, -self.y_)
488 }
489}
490
491impl<T1: Clone + Num + Neg<Output = T1>, T2: Clone + Num + Neg<Output = T2>> Neg
492 for &Vector2<T1, T2>
493{
494 type Output = Vector2<T1, T2>;
495
496 #[inline]
497 fn neg(self) -> Self::Output {
498 -self.clone()
499 }
500}
501
502macro_rules! scalar_arithmetic {
503 (@forward $imp:ident::$method:ident for $($scalar:ident),*) => (
504 impl<'a, T1: Clone + Num> $imp<&'a T1> for Vector2<T1, T1> {
505 type Output = Vector2<T1, T1>;
506
507 #[inline]
508 fn $method(self, other: &T1) -> Self::Output {
509 self.$method(other.clone())
510 }
511 }
512 impl<'a, T1: Clone + Num> $imp<T1> for &'a Vector2<T1, T1> {
513 type Output = Vector2<T1, T1>;
514
515 #[inline]
516 fn $method(self, other: T1) -> Self::Output {
517 self.clone().$method(other)
518 }
519 }
520 impl<'a, 'b, T1: Clone + Num> $imp<&'a T1> for &'b Vector2<T1, T1> {
521 type Output = Vector2<T1, T1>;
522
523 #[inline]
524 fn $method(self, other: &T1) -> Self::Output {
525 self.clone().$method(other.clone())
526 }
527 }
528 $(
529 impl<'a> $imp<&'a Vector2<$scalar, $scalar>> for $scalar {
530 type Output = Vector2<$scalar, $scalar>;
531
532 #[inline]
533 fn $method(self, other: &Vector2<$scalar, $scalar>) -> Vector2<$scalar, $scalar> {
534 self.$method(other.clone())
535 }
536 }
537 impl<'a> $imp<Vector2<$scalar, $scalar>> for &'a $scalar {
538 type Output = Vector2<$scalar, $scalar>;
539
540 #[inline]
541 fn $method(self, other: Vector2<$scalar, $scalar>) -> Vector2<$scalar, $scalar> {
542 self.clone().$method(other)
543 }
544 }
545 impl<'a, 'b> $imp<&'a Vector2<$scalar, $scalar>> for &'b $scalar {
546 type Output = Vector2<$scalar, $scalar>;
547
548 #[inline]
549 fn $method(self, other: &Vector2<$scalar, $scalar>) -> Vector2<$scalar, $scalar> {
550 self.clone().$method(other.clone())
551 }
552 }
553 )*
554 );
555 ($($scalar:ident),*) => (
556 scalar_arithmetic!(@forward Mul::mul for $($scalar),*);
557 $(
561 impl Mul<Vector2<$scalar, $scalar>> for $scalar {
562 type Output = Vector2<$scalar, $scalar>;
563
564 #[inline]
565 fn mul(self, other: Vector2<$scalar, $scalar>) -> Self::Output {
566 Self::Output::new(self * other.x_, self * other.y_)
567 }
568 }
569
570 )*
571 );
572}
573
574impl<T1: Clone + Num> Mul<T1> for Vector2<T1, T1> {
575 type Output = Vector2<T1, T1>;
576
577 #[inline]
578 fn mul(self, other: T1) -> Self::Output {
579 Self::Output::new(self.x_ * other.clone(), self.y_ * other)
580 }
581}
582
583impl<T1: Clone + Num> Div<T1> for Vector2<T1, T1> {
584 type Output = Self;
585
586 #[inline]
587 fn div(self, other: T1) -> Self::Output {
588 Self::Output::new(self.x_ / other.clone(), self.y_ / other)
589 }
590}
591
592impl<T1: Clone + Num> Rem<T1> for Vector2<T1, T1> {
593 type Output = Vector2<T1, T1>;
594
595 #[inline]
596 fn rem(self, other: T1) -> Self::Output {
597 Self::Output::new(self.x_ % other.clone(), self.y_ % other)
598 }
599}
600
601scalar_arithmetic!(usize, u8, u16, u32, u64, u128, isize, i8, i16, i32, i64, i128, f32, f64);
602
603impl<T1: Clone + Num, T2: Clone + Num> Zero for Vector2<T1, T2> {
605 #[inline]
606 fn zero() -> Self {
607 Self::new(Zero::zero(), Zero::zero())
608 }
609
610 #[inline]
611 fn is_zero(&self) -> bool {
612 self.x_.is_zero() && self.y_.is_zero()
613 }
614
615 #[inline]
616 fn set_zero(&mut self) {
617 self.x_.set_zero();
618 self.y_.set_zero();
619 }
620}
621
622#[cfg(test)]
623fn hash<T: hash::Hash>(x: &T) -> u64 {
624 use std::collections::hash_map::RandomState;
625 use std::hash::{BuildHasher, Hasher};
626 let mut hasher = <RandomState as BuildHasher>::Hasher::new();
627 x.hash(&mut hasher);
628 hasher.finish()
629}
630
631#[cfg(test)]
632mod test {
633 #![allow(non_upper_case_globals)]
634
635 use super::{hash, Vector2};
636 use core::f64;
637 use num_traits::Zero;
638
639 pub const _0_0v: Vector2<f64, f64> = Vector2 { x_: 0.0, y_: 0.0 };
640 pub const _1_0v: Vector2<f64, f64> = Vector2 { x_: 1.0, y_: 0.0 };
641 pub const _1_1v: Vector2<f64, f64> = Vector2 { x_: 1.0, y_: 1.0 };
642 pub const _0_1v: Vector2<f64, f64> = Vector2 { x_: 0.0, y_: 1.0 };
643 pub const _neg1_1v: Vector2<f64, f64> = Vector2 { x_: -1.0, y_: 1.0 };
644 pub const _05_05v: Vector2<f64, f64> = Vector2 { x_: 0.5, y_: 0.5 };
645 pub const all_consts: [Vector2<f64, f64>; 5] = [_0_0v, _1_0v, _1_1v, _neg1_1v, _05_05v];
646 pub const _4_2v: Vector2<f64, f64> = Vector2 { x_: 4.0, y_: 2.0 };
647
648 pub const _0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
649 x_: _0_0v,
650 y_: _0_0v,
651 };
652
653 pub const _0_0_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
655 x_: _0_0v,
656 y_: _0_0v,
657 };
658 pub const _1_0_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
659 x_: _1_0v,
660 y_: _0_0v,
661 };
662 pub const _1_1_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
663 x_: _1_1v,
664 y_: _0_0v,
665 };
666 pub const _0_1_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
667 x_: _0_1v,
668 y_: _0_0v,
669 };
670 pub const _neg1_1_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
671 x_: _neg1_1v,
672 y_: _0_0v,
673 };
674 pub const _05_05_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
675 x_: _05_05v,
676 y_: _0_0v,
677 };
678 pub const _0_0_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
679 x_: _0_0v,
680 y_: _1_0v,
681 };
682 pub const _1_0_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
683 x_: _1_0v,
684 y_: _1_0v,
685 };
686 pub const _1_1_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
687 x_: _1_1v,
688 y_: _1_0v,
689 };
690 pub const _0_1_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
691 x_: _0_1v,
692 y_: _1_0v,
693 };
694 pub const _neg1_1_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
695 x_: _neg1_1v,
696 y_: _1_0v,
697 };
698 pub const _05_05_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
699 x_: _05_05v,
700 y_: _1_0v,
701 };
702 pub const _0_0_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
703 x_: _0_0v,
704 y_: _0_1v,
705 };
706 pub const _1_0_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
707 x_: _1_0v,
708 y_: _0_1v,
709 };
710 pub const _1_1_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
711 x_: _1_1v,
712 y_: _0_1v,
713 };
714 pub const _0_1_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
715 x_: _0_1v,
716 y_: _0_1v,
717 };
718 pub const _neg1_1_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
719 x_: _neg1_1v,
720 y_: _0_1v,
721 };
722 pub const _05_05_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
723 x_: _05_05v,
724 y_: _0_1v,
725 };
726
727 #[test]
728 fn test_consts() {
729 fn test(c: Vector2<f64, f64>, r: f64, i: f64) {
731 assert_eq!(c, Vector2::new(r, i));
732 }
733 test(_0_0v, 0.0, 0.0);
734 test(_1_0v, 1.0, 0.0);
735 test(_1_1v, 1.0, 1.0);
736 test(_neg1_1v, -1.0, 1.0);
737 test(_05_05v, 0.5, 0.5);
738 assert_eq!(_0_0v, Zero::zero());
739 }
740
741 #[test]
742 fn test_scale_unscale() {
743 assert_eq!(_05_05v.scale(2.0), _1_1v);
744 assert_eq!(_1_1v.unscale(2.0), _05_05v);
745 for &c in all_consts.iter() {
746 assert_eq!(c.scale(2.0).unscale(2.0), c);
747 }
748 }
749
750 #[test]
751 fn test_hash() {
752 let a = Vector2::new(0i32, 0i32);
753 let b = Vector2::new(1i32, 0i32);
754 let c = Vector2::new(0i32, 1i32);
755 assert!(hash(&a) != hash(&b));
756 assert!(hash(&b) != hash(&c));
757 assert!(hash(&c) != hash(&a));
758 }
759
760 #[test]
761 fn test_zero() {
762 assert_eq!(_0_0v, Vector2::zero());
763 }
764
765 #[test]
766 fn test_is_zero() {
767 assert!(Vector2::<i32, i32>::zero().is_zero());
768 assert!(!_1_1v.is_zero());
769 }
770
771 #[test]
772 fn test_set_zero() {
773 let mut v = _1_1v;
774 v.set_zero();
775 assert!(v.is_zero());
776 }
777
778 #[test]
779 fn test_neg() {
780 assert_eq!(-(-_1_1v), _1_1v);
781 }
782
783 #[test]
784 fn test_scalar_arithmetic() {
785 assert_eq!(_1_1v * 0.5, _05_05v);
786 assert_eq!(_1_1v / 2.0, _05_05v);
787 assert_eq!(_4_2v % 2.0, _0_0v);
788 assert_eq!(0.5 * _1_1v, _05_05v);
789 }
790
791 #[test]
792 fn test_scalar_arithmetic_ref() {
793 assert_eq!(_1_1v * 0.5, _05_05v);
794 assert_eq!(0.5 * _1_1v, _05_05v);
795 }
796
797 #[test]
798 fn test_dot() {
799 assert_eq!(_1_1v.dot(&_1_1v), 2.0);
800 assert_eq!(_1_1v.dot(&_neg1_1v), 0.0);
801 assert_eq!(_1_1v.dot(&_0_1v), 1.0);
802 }
803
804 #[test]
805 fn test_cross() {
806 assert_eq!(_1_1v.cross(&_1_1v), 0.0);
807 assert_eq!(_1_1v.cross(&_neg1_1v), 2.0);
808 assert_eq!(_1_1v.cross(&_0_1v), 1.0);
809 }
810
811 #[test]
823 fn test_l1_norm() {
824 assert_eq!(_1_1v.l1_norm(), 2.0);
825 assert_eq!(_0_1v.l1_norm(), 1.0);
826 assert_eq!(_neg1_1v.l1_norm(), 2.0);
827 assert_eq!(_05_05v.l1_norm(), 1.0);
828 assert_eq!(_1_0v.l1_norm(), 1.0);
829 assert_eq!(_0_0v.l1_norm(), 0.0);
830 assert_eq!(_4_2v.l1_norm(), 6.0);
831 }
832
833 #[test]
834 fn test_norm_inf() {
835 assert_eq!(_1_1v.norm_inf(), 1.0);
836 assert_eq!(_0_1v.norm_inf(), 1.0);
837 assert_eq!(_neg1_1v.norm_inf(), 1.0);
838 assert_eq!(_05_05v.norm_inf(), 0.5);
839 assert_eq!(_1_0v.norm_inf(), 1.0);
840 assert_eq!(_0_0v.norm_inf(), 0.0);
841 assert_eq!(_4_2v.norm_inf(), 4.0);
842 }
843
844 #[test]
845 fn test_add_assign() {
846 let mut a = _0_1v;
847 a += _1_0v;
848 assert_eq!(a, _1_1v);
849 }
850
851 #[test]
852 fn test_sub_assign() {
853 let mut a = _1_1v;
854 a -= _1_1v;
855 assert_eq!(a, _0_0v);
856 }
857
858 #[test]
859 fn test_mul_assign() {
860 let mut a = _05_05v;
861 a *= 2.0;
862 assert_eq!(a, _1_1v);
863 }
864
865 #[test]
866 fn test_div_assign() {
867 let mut a = _1_1v;
868 a /= 2.0;
869 assert_eq!(a, _05_05v);
870 }
871
872 #[test]
873 fn test_consts_vv() {
874 fn test(c: Vector2<Vector2<f64, f64>, Vector2<f64, f64>>, w: f64, x: f64, y: f64, z: f64) {
876 assert_eq!(c, Vector2::new(Vector2::new(w, x), Vector2::new(y, z)));
877 }
878
879 test(_0_0vv, 0.0, 0.0, 0.0, 0.0);
880 test(_0_0_0_0vv, 0.0, 0.0, 0.0, 0.0);
881 test(_1_0_0_0vv, 1.0, 0.0, 0.0, 0.0);
882 test(_1_1_0_0vv, 1.0, 1.0, 0.0, 0.0);
883 test(_0_1_0_0vv, 0.0, 1.0, 0.0, 0.0);
884 test(_neg1_1_0_0vv, -1.0, 1.0, 0.0, 0.0);
885 test(_05_05_0_0vv, 0.5, 0.5, 0.0, 0.0);
886 test(_0_0_1_0vv, 0.0, 0.0, 1.0, 0.0);
887 test(_1_0_1_0vv, 1.0, 0.0, 1.0, 0.0);
888 test(_1_1_1_0vv, 1.0, 1.0, 1.0, 0.0);
889 test(_0_1_1_0vv, 0.0, 1.0, 1.0, 0.0);
890 test(_neg1_1_1_0vv, -1.0, 1.0, 1.0, 0.0);
891 test(_05_05_1_0vv, 0.5, 0.5, 1.0, 0.0);
892 }
893
894 }