1use core::ops::{Add, Div, Mul, Neg, Rem, Sub};
2use num_traits::{Num, Signed, Zero};
3
4#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug, Default)]
13pub struct Vector2<T1, T2> {
15 pub x_: T1,
17 pub y_: T2,
19}
20
21impl<T1, T2> Vector2<T1, T2> {
22 #[inline]
44 pub const fn new(x_: T1, y_: T2) -> Self {
45 Vector2 { x_, y_ }
46 }
47}
48
49impl<T1: Clone + Num> Vector2<T1, T1> {
50 #[inline]
70 pub fn dot(&self, other: &Self) -> T1 {
71 self.x_.clone() * other.x_.clone() + self.y_.clone() * other.y_.clone()
72 }
73
74 #[inline]
90 pub fn cross(&self, other: &Self) -> T1 {
91 self.x_.clone() * other.y_.clone() - self.y_.clone() * other.x_.clone()
92 }
93
94 #[inline]
120 pub fn scale(&self, t: T1) -> Self {
121 Self::new(self.x_.clone() * t.clone(), self.y_.clone() * t)
122 }
123
124 #[inline]
146 pub fn unscale(&self, t: T1) -> Self {
147 Self::new(self.x_.clone() / t.clone(), self.y_.clone() / t)
148 }
149}
150
151impl<T1: Clone + Signed> Vector2<T1, T1> {
152 #[inline]
170 pub fn l1_norm(&self) -> T1 {
171 self.x_.abs() + self.y_.abs()
172 }
173}
174
175impl<T1: Clone + PartialOrd> Vector2<T1, T1> {
176 #[inline]
192 pub fn norm_inf(&self) -> T1 {
193 if self.x_ > self.y_ {
194 self.x_.clone()
195 } else {
196 self.y_.clone()
197 }
198 }
199}
200
201impl<T1: Clone + Num, T2: Clone + Num> Add<Vector2<T1, T2>> for Vector2<T1, T2> {
203 type Output = Self;
204
205 #[inline]
222 fn add(self, other: Self) -> Self::Output {
223 Self::Output::new(self.x_ + other.x_, self.y_ + other.y_)
224 }
225}
226
227impl<T1: Clone + Num, T2: Clone + Num> Sub<Vector2<T1, T2>> for Vector2<T1, T2> {
229 type Output = Self;
230
231 #[inline]
248 fn sub(self, other: Self) -> Self::Output {
249 Self::Output::new(self.x_ - other.x_, self.y_ - other.y_)
250 }
251}
252
253mod opassign {
256 use core::ops::{AddAssign, DivAssign, MulAssign, SubAssign};
257
258 use num_traits::NumAssign;
259
260 use crate::Vector2;
261
262 impl<T1: Clone + NumAssign, T2: Clone + NumAssign> AddAssign for Vector2<T1, T2> {
263 fn add_assign(&mut self, other: Self) {
285 self.x_ += other.x_;
286 self.y_ += other.y_;
287 }
288 }
289
290 impl<T1: Clone + NumAssign, T2: Clone + NumAssign> SubAssign for Vector2<T1, T2> {
291 fn sub_assign(&mut self, other: Self) {
311 self.x_ -= other.x_;
312 self.y_ -= other.y_;
313 }
314 }
315
316 impl<T1: Clone + NumAssign> MulAssign<T1> for Vector2<T1, T1> {
317 fn mul_assign(&mut self, other: T1) {
335 self.x_ *= other.clone();
336 self.y_ *= other;
337 }
338 }
339
340 impl<T1: Clone + NumAssign> DivAssign<T1> for Vector2<T1, T1> {
341 fn div_assign(&mut self, other: T1) {
359 self.x_ /= other.clone();
360 self.y_ /= other;
361 }
362 }
363
364 macro_rules! forward_op_assign1 {
365 (impl $imp:ident, $method:ident) => {
366 impl<'a, T1: Clone + NumAssign, T2: Clone + NumAssign> $imp<&'a Vector2<T1, T2>>
367 for Vector2<T1, T2>
368 {
369 #[inline]
370 fn $method(&mut self, other: &Self) {
371 self.$method(other.clone())
372 }
373 }
374 };
375 }
376
377 macro_rules! forward_op_assign2 {
378 (impl $imp:ident, $method:ident) => {
379 impl<'a, T1: Clone + NumAssign> $imp<&'a T1> for Vector2<T1, T1> {
380 #[inline]
381 fn $method(&mut self, other: &T1) {
382 self.$method(other.clone())
383 }
384 }
385 };
386 }
387
388 forward_op_assign1!(impl AddAssign, add_assign);
389 forward_op_assign1!(impl SubAssign, sub_assign);
390 forward_op_assign2!(impl MulAssign, mul_assign);
391 forward_op_assign2!(impl DivAssign, div_assign);
392}
393
394impl<T1: Clone + Num + Neg<Output = T1>, T2: Clone + Num + Neg<Output = T2>> Neg
395 for Vector2<T1, T2>
396{
397 type Output = Self;
398
399 #[inline]
412 fn neg(self) -> Self::Output {
413 Self::Output::new(-self.x_, -self.y_)
414 }
415}
416
417impl<T1: Clone + Num + Neg<Output = T1>, T2: Clone + Num + Neg<Output = T2>> Neg
418 for &Vector2<T1, T2>
419{
420 type Output = Vector2<T1, T2>;
421
422 #[inline]
423 fn neg(self) -> Self::Output {
424 -self.clone()
425 }
426}
427
428macro_rules! scalar_arithmetic {
429 (@forward $imp:ident::$method:ident for $($scalar:ident),*) => (
430 impl<'a, T1: Clone + Num> $imp<&'a T1> for Vector2<T1, T1> {
431 type Output = Vector2<T1, T1>;
432
433 #[inline]
434 fn $method(self, other: &T1) -> Self::Output {
435 self.$method(other.clone())
436 }
437 }
438 impl<'a, T1: Clone + Num> $imp<T1> for &'a Vector2<T1, T1> {
439 type Output = Vector2<T1, T1>;
440
441 #[inline]
442 fn $method(self, other: T1) -> Self::Output {
443 self.clone().$method(other)
444 }
445 }
446 impl<'a, 'b, T1: Clone + Num> $imp<&'a T1> for &'b Vector2<T1, T1> {
447 type Output = Vector2<T1, T1>;
448
449 #[inline]
450 fn $method(self, other: &T1) -> Self::Output {
451 self.clone().$method(other.clone())
452 }
453 }
454 $(
455 impl<'a> $imp<&'a Vector2<$scalar, $scalar>> for $scalar {
456 type Output = Vector2<$scalar, $scalar>;
457
458 #[inline]
459 fn $method(self, other: &Vector2<$scalar, $scalar>) -> Vector2<$scalar, $scalar> {
460 self.$method(other.clone())
461 }
462 }
463 impl<'a> $imp<Vector2<$scalar, $scalar>> for &'a $scalar {
464 type Output = Vector2<$scalar, $scalar>;
465
466 #[inline]
467 fn $method(self, other: Vector2<$scalar, $scalar>) -> Vector2<$scalar, $scalar> {
468 self.clone().$method(other)
469 }
470 }
471 impl<'a, 'b> $imp<&'a Vector2<$scalar, $scalar>> for &'b $scalar {
472 type Output = Vector2<$scalar, $scalar>;
473
474 #[inline]
475 fn $method(self, other: &Vector2<$scalar, $scalar>) -> Vector2<$scalar, $scalar> {
476 self.clone().$method(other.clone())
477 }
478 }
479 )*
480 );
481 ($($scalar:ident),*) => (
482 scalar_arithmetic!(@forward Mul::mul for $($scalar),*);
483 $(
487 impl Mul<Vector2<$scalar, $scalar>> for $scalar {
488 type Output = Vector2<$scalar, $scalar>;
489
490 #[inline]
491 fn mul(self, other: Vector2<$scalar, $scalar>) -> Self::Output {
492 Self::Output::new(self * other.x_, self * other.y_)
493 }
494 }
495
496 )*
497 );
498}
499
500impl<T1: Clone + Num> Mul<T1> for Vector2<T1, T1> {
501 type Output = Vector2<T1, T1>;
502
503 #[inline]
504 fn mul(self, other: T1) -> Self::Output {
505 Self::Output::new(self.x_ * other.clone(), self.y_ * other)
506 }
507}
508
509impl<T1: Clone + Num> Div<T1> for Vector2<T1, T1> {
510 type Output = Self;
511
512 #[inline]
513 fn div(self, other: T1) -> Self::Output {
514 Self::Output::new(self.x_ / other.clone(), self.y_ / other)
515 }
516}
517
518impl<T1: Clone + Num> Rem<T1> for Vector2<T1, T1> {
519 type Output = Vector2<T1, T1>;
520
521 #[inline]
522 fn rem(self, other: T1) -> Self::Output {
523 Self::Output::new(self.x_ % other.clone(), self.y_ % other)
524 }
525}
526
527scalar_arithmetic!(usize, u8, u16, u32, u64, u128, isize, i8, i16, i32, i64, i128, f32, f64);
528
529impl<T1: Clone + Num + Add, T2: Clone + Num + Add> Zero for Vector2<T1, T2> {
531 #[inline]
532 fn zero() -> Self {
533 Self::new(Zero::zero(), Zero::zero())
534 }
535
536 #[inline]
537 fn is_zero(&self) -> bool {
538 self.x_.is_zero() && self.y_.is_zero()
539 }
540
541 #[inline]
542 fn set_zero(&mut self) {
543 self.x_.set_zero();
544 self.y_.set_zero();
545 }
546}
547
548#[cfg(test)]
549mod test {
550 #![allow(non_upper_case_globals)]
551
552 use super::Vector2;
553 use core::f64;
554 use num_traits::Zero;
555 use std::hash;
556
557 fn hash<T: hash::Hash>(x: &T) -> u64 {
558 use std::collections::hash_map::RandomState;
559 use std::hash::{BuildHasher, Hasher};
560 let mut hasher = <RandomState as BuildHasher>::Hasher::new();
561 x.hash(&mut hasher);
562 hasher.finish()
563 }
564
565 pub const _0_0v: Vector2<f64, f64> = Vector2 { x_: 0.0, y_: 0.0 };
566 pub const _1_0v: Vector2<f64, f64> = Vector2 { x_: 1.0, y_: 0.0 };
567 pub const _1_1v: Vector2<f64, f64> = Vector2 { x_: 1.0, y_: 1.0 };
568 pub const _0_1v: Vector2<f64, f64> = Vector2 { x_: 0.0, y_: 1.0 };
569 pub const _neg1_1v: Vector2<f64, f64> = Vector2 { x_: -1.0, y_: 1.0 };
570 pub const _05_05v: Vector2<f64, f64> = Vector2 { x_: 0.5, y_: 0.5 };
571 pub const all_consts: [Vector2<f64, f64>; 5] = [_0_0v, _1_0v, _1_1v, _neg1_1v, _05_05v];
572 pub const _4_2v: Vector2<f64, f64> = Vector2 { x_: 4.0, y_: 2.0 };
573
574 pub const _0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
575 x_: _0_0v,
576 y_: _0_0v,
577 };
578
579 pub const _0_0_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
581 x_: _0_0v,
582 y_: _0_0v,
583 };
584 pub const _1_0_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
585 x_: _1_0v,
586 y_: _0_0v,
587 };
588 pub const _1_1_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
589 x_: _1_1v,
590 y_: _0_0v,
591 };
592 pub const _0_1_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
593 x_: _0_1v,
594 y_: _0_0v,
595 };
596 pub const _neg1_1_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
597 x_: _neg1_1v,
598 y_: _0_0v,
599 };
600 pub const _05_05_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
601 x_: _05_05v,
602 y_: _0_0v,
603 };
604 pub const _0_0_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
605 x_: _0_0v,
606 y_: _1_0v,
607 };
608 pub const _1_0_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
609 x_: _1_0v,
610 y_: _1_0v,
611 };
612 pub const _1_1_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
613 x_: _1_1v,
614 y_: _1_0v,
615 };
616 pub const _0_1_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
617 x_: _0_1v,
618 y_: _1_0v,
619 };
620 pub const _neg1_1_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
621 x_: _neg1_1v,
622 y_: _1_0v,
623 };
624 pub const _05_05_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
625 x_: _05_05v,
626 y_: _1_0v,
627 };
628 pub const _0_0_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
629 x_: _0_0v,
630 y_: _0_1v,
631 };
632 pub const _1_0_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
633 x_: _1_0v,
634 y_: _0_1v,
635 };
636 pub const _1_1_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
637 x_: _1_1v,
638 y_: _0_1v,
639 };
640 pub const _0_1_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
641 x_: _0_1v,
642 y_: _0_1v,
643 };
644 pub const _neg1_1_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
645 x_: _neg1_1v,
646 y_: _0_1v,
647 };
648 pub const _05_05_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
649 x_: _05_05v,
650 y_: _0_1v,
651 };
652
653 #[test]
654 fn test_consts() {
655 fn test(c: Vector2<f64, f64>, r: f64, i: f64) {
657 assert_eq!(c, Vector2::new(r, i));
658 }
659 test(_0_0v, 0.0, 0.0);
660 test(_1_0v, 1.0, 0.0);
661 test(_1_1v, 1.0, 1.0);
662 test(_neg1_1v, -1.0, 1.0);
663 test(_05_05v, 0.5, 0.5);
664 assert_eq!(_0_0v, Zero::zero());
665 }
666
667 #[test]
668 fn test_scale_unscale() {
669 assert_eq!(_05_05v.scale(2.0), _1_1v);
670 assert_eq!(_1_1v.unscale(2.0), _05_05v);
671 for &c in all_consts.iter() {
672 assert_eq!(c.scale(2.0).unscale(2.0), c);
673 }
674 }
675
676 #[test]
677 fn test_hash() {
678 let a = Vector2::new(0i32, 0i32);
679 let b = Vector2::new(1i32, 0i32);
680 let c = Vector2::new(0i32, 1i32);
681 assert!(hash(&a) != hash(&b));
682 assert!(hash(&b) != hash(&c));
683 assert!(hash(&c) != hash(&a));
684 }
685
686 #[test]
687 fn test_zero() {
688 assert_eq!(_0_0v, Vector2::zero());
689 }
690
691 #[test]
692 fn test_is_zero() {
693 assert!(Vector2::<i32, i32>::zero().is_zero());
694 assert!(!_1_1v.is_zero());
695 }
696
697 #[test]
698 fn test_set_zero() {
699 let mut v = _1_1v;
700 v.set_zero();
701 assert!(v.is_zero());
702 }
703
704 #[test]
705 fn test_neg() {
706 assert_eq!(-(-_1_1v), _1_1v);
707 }
708
709 #[test]
710 fn test_scalar_arithmetic() {
711 assert_eq!(_1_1v * 0.5, _05_05v);
712 assert_eq!(_1_1v / 2.0, _05_05v);
713 assert_eq!(_4_2v % 2.0, _0_0v);
714 assert_eq!(0.5 * _1_1v, _05_05v);
715 }
716
717 #[test]
718 fn test_scalar_arithmetic_ref() {
719 assert_eq!(_1_1v * 0.5, _05_05v);
720 assert_eq!(0.5 * _1_1v, _05_05v);
721 }
722
723 #[test]
724 fn test_dot() {
725 assert_eq!(_1_1v.dot(&_1_1v), 2.0);
726 assert_eq!(_1_1v.dot(&_neg1_1v), 0.0);
727 assert_eq!(_1_1v.dot(&_0_1v), 1.0);
728 }
729
730 #[test]
731 fn test_cross() {
732 assert_eq!(_1_1v.cross(&_1_1v), 0.0);
733 assert_eq!(_1_1v.cross(&_neg1_1v), 2.0);
734 assert_eq!(_1_1v.cross(&_0_1v), 1.0);
735 }
736
737 #[test]
749 fn test_l1_norm() {
750 assert_eq!(_1_1v.l1_norm(), 2.0);
751 assert_eq!(_0_1v.l1_norm(), 1.0);
752 assert_eq!(_neg1_1v.l1_norm(), 2.0);
753 assert_eq!(_05_05v.l1_norm(), 1.0);
754 assert_eq!(_1_0v.l1_norm(), 1.0);
755 assert_eq!(_0_0v.l1_norm(), 0.0);
756 assert_eq!(_4_2v.l1_norm(), 6.0);
757 }
758
759 #[test]
760 fn test_norm_inf() {
761 assert_eq!(_1_1v.norm_inf(), 1.0);
762 assert_eq!(_0_1v.norm_inf(), 1.0);
763 assert_eq!(_neg1_1v.norm_inf(), 1.0);
764 assert_eq!(_05_05v.norm_inf(), 0.5);
765 assert_eq!(_1_0v.norm_inf(), 1.0);
766 assert_eq!(_0_0v.norm_inf(), 0.0);
767 assert_eq!(_4_2v.norm_inf(), 4.0);
768 }
769
770 #[test]
771 fn test_add_assign() {
772 let mut a = _0_1v;
773 a += _1_0v;
774 assert_eq!(a, _1_1v);
775 }
776
777 #[test]
778 fn test_sub_assign() {
779 let mut a = _1_1v;
780 a -= _1_1v;
781 assert_eq!(a, _0_0v);
782 }
783
784 #[test]
785 fn test_mul_assign() {
786 let mut a = _05_05v;
787 a *= 2.0;
788 assert_eq!(a, _1_1v);
789 }
790
791 #[test]
792 fn test_div_assign() {
793 let mut a = _1_1v;
794 a /= 2.0;
795 assert_eq!(a, _05_05v);
796 }
797
798 #[test]
799 fn test_rem() {
800 assert_eq!(_4_2v % 3.0, Vector2::new(1.0, 2.0));
801 }
802
803 #[test]
804 fn test_sub_more() {
805 assert_eq!(_1_1v - _0_1v, _1_0v);
806 assert_eq!(_0_1v - _1_0v, Vector2::new(-1.0, 1.0));
807 }
808
809 #[test]
810 fn test_add_more() {
811 assert_eq!(_1_0v + _0_1v, _1_1v);
812 }
813
814 #[test]
815 fn test_mul_more() {
816 assert_eq!(_1_1v * 2.0, Vector2::new(2.0, 2.0));
817 }
818
819 #[test]
820 fn test_dot_more_cases() {
821 assert_eq!(_0_0v.dot(&_1_1v), 0.0);
822 assert_eq!(_1_1v.dot(&_0_0v), 0.0);
823 assert_eq!(_neg1_1v.dot(&_1_1v), 0.0);
824 }
825
826 #[test]
827 fn test_cross_more_cases() {
828 assert_eq!(_0_0v.cross(&_1_1v), 0.0);
829 assert_eq!(_1_1v.cross(&_0_0v), 0.0);
830 assert_eq!(_neg1_1v.cross(&_1_1v), -2.0);
831 }
832
833 #[test]
834 fn test_l1_norm_more_cases() {
835 assert_eq!(_0_0v.l1_norm(), 0.0);
836 assert_eq!(_neg1_1v.l1_norm(), 2.0);
837 }
838
839 #[test]
840 fn test_norm_inf_more_cases() {
841 assert_eq!(_0_0v.norm_inf(), 0.0);
842 assert_eq!(_neg1_1v.norm_inf(), 1.0);
843 }
844
845 #[test]
846 fn test_scalar_arithmetic_more_cases() {
847 assert_eq!(_0_0v * 2.0, _0_0v);
848 assert_eq!(_1_1v * 0.0, _0_0v);
849 assert_eq!(_1_1v * 1.0, _1_1v);
850 assert_eq!(_1_1v * -1.0, -_1_1v);
851 }
852
853 #[test]
854 fn test_consts_vv() {
855 fn test(c: Vector2<Vector2<f64, f64>, Vector2<f64, f64>>, w: f64, x: f64, y: f64, z: f64) {
857 assert_eq!(c, Vector2::new(Vector2::new(w, x), Vector2::new(y, z)));
858 }
859
860 test(_0_0vv, 0.0, 0.0, 0.0, 0.0);
861 test(_0_0_0_0vv, 0.0, 0.0, 0.0, 0.0);
862 test(_1_0_0_0vv, 1.0, 0.0, 0.0, 0.0);
863 test(_1_1_0_0vv, 1.0, 1.0, 0.0, 0.0);
864 test(_0_1_0_0vv, 0.0, 1.0, 0.0, 0.0);
865 test(_neg1_1_0_0vv, -1.0, 1.0, 0.0, 0.0);
866 test(_05_05_0_0vv, 0.5, 0.5, 0.0, 0.0);
867 test(_0_0_1_0vv, 0.0, 0.0, 1.0, 0.0);
868 test(_1_0_1_0vv, 1.0, 0.0, 1.0, 0.0);
869 test(_1_1_1_0vv, 1.0, 1.0, 1.0, 0.0);
870 test(_0_1_1_0vv, 0.0, 1.0, 1.0, 0.0);
871 test(_neg1_1_1_0vv, -1.0, 1.0, 1.0, 0.0);
872 test(_05_05_1_0vv, 0.5, 0.5, 1.0, 0.0);
873 }
874
875 }