1use core::ops::{Add, Div, Mul, Neg, Rem, Sub};
3use num_traits::{Num, Signed, Zero};
4
5#[cfg_attr(feature = "doc-images", doc = svgbobdoc::transform!(
22))]
32#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug, Default)]
33pub struct Vector2<T> {
34 pub x_: T,
36 pub y_: T,
38}
39
40impl<T> Vector2<T> {
41 #[inline]
64 pub const fn new(x_: T, y_: T) -> Self {
65 Vector2 { x_, y_ }
66 }
67}
68
69impl<T: Clone + Num> Vector2<T> {
70 #[inline]
94 pub fn dot(&self, other: &Self) -> T {
95 self.x_.clone() * other.x_.clone() + self.y_.clone() * other.y_.clone()
96 }
97
98 #[inline]
122 pub fn cross(&self, other: &Self) -> T {
123 self.x_.clone() * other.y_.clone() - self.y_.clone() * other.x_.clone()
124 }
125
126 #[inline]
145 pub fn norm_sqr(&self) -> T {
146 self.dot(self)
147 }
148
149 #[inline]
172 pub fn scale(&self, alpha: T) -> Self {
173 Self::new(self.x_.clone() * alpha.clone(), self.y_.clone() * alpha)
174 }
175
176 #[inline]
198 pub fn unscale(&self, alpha: T) -> Self {
199 Self::new(self.x_.clone() / alpha.clone(), self.y_.clone() / alpha)
200 }
201}
202
203impl<T: Clone + Signed> Vector2<T> {
204 #[inline]
224 pub fn l1_norm(&self) -> T {
225 self.x_.abs() + self.y_.abs()
226 }
227}
228
229impl<T: Clone + Signed + PartialOrd> Vector2<T> {
230 #[inline]
244 pub fn norm_inf(&self) -> T {
245 let ax = self.x_.abs();
246 let ay = self.y_.abs();
247 if ax > ay {
248 ax
249 } else {
250 ay
251 }
252 }
253}
254
255macro_rules! forward_xf_xf_binop {
256 (impl $imp:ident, $method:ident) => {
257 impl<'a, 'b, T: Clone + Num> $imp<&'b Vector2<T>> for &'a Vector2<T> {
258 type Output = Vector2<T>;
259
260 #[inline]
261 fn $method(self, other: &Vector2<T>) -> Self::Output {
262 self.clone().$method(other.clone())
263 }
264 }
265 };
266}
267
268macro_rules! forward_xf_val_binop {
269 (impl $imp:ident, $method:ident) => {
270 impl<'a, T: Clone + Num> $imp<Vector2<T>> for &'a Vector2<T> {
271 type Output = Vector2<T>;
272
273 #[inline]
274 fn $method(self, other: Vector2<T>) -> Self::Output {
275 self.clone().$method(other)
276 }
277 }
278 };
279}
280
281macro_rules! forward_val_xf_binop {
282 (impl $imp:ident, $method:ident) => {
283 impl<'a, T: Clone + Num> $imp<&'a Vector2<T>> for Vector2<T> {
284 type Output = Vector2<T>;
285
286 #[inline]
287 fn $method(self, other: &Vector2<T>) -> Self::Output {
288 self.$method(other.clone())
289 }
290 }
291 };
292}
293
294macro_rules! forward_all_binop {
295 (impl $imp:ident, $method:ident) => {
296 forward_xf_xf_binop!(impl $imp, $method);
297 forward_xf_val_binop!(impl $imp, $method);
298 forward_val_xf_binop!(impl $imp, $method);
299 };
300}
301
302forward_all_binop!(impl Add, add);
304
305impl<T: Clone + Num> Add<Vector2<T>> for Vector2<T> {
309 type Output = Self;
310
311 #[inline]
312 fn add(self, other: Self) -> Self::Output {
313 Self::Output::new(self.x_ + other.x_, self.y_ + other.y_)
314 }
315}
316
317forward_all_binop!(impl Sub, sub);
318
319impl<T: Clone + Num> Sub<Vector2<T>> for Vector2<T> {
323 type Output = Self;
324
325 #[inline]
326 fn sub(self, other: Self) -> Self::Output {
327 Self::Output::new(self.x_ - other.x_, self.y_ - other.y_)
328 }
329}
330
331mod opassign {
334 use core::ops::{AddAssign, DivAssign, MulAssign, SubAssign};
335
336 use num_traits::NumAssign;
337
338 use crate::Vector2;
339
340 impl<T: Clone + NumAssign> AddAssign for Vector2<T> {
341 fn add_assign(&mut self, other: Self) {
342 self.x_ += other.x_;
343 self.y_ += other.y_;
344 }
345 }
346
347 impl<T: Clone + NumAssign> SubAssign for Vector2<T> {
348 fn sub_assign(&mut self, other: Self) {
349 self.x_ -= other.x_;
350 self.y_ -= other.y_;
351 }
352 }
353
354 impl<T: Clone + NumAssign> MulAssign<T> for Vector2<T> {
355 fn mul_assign(&mut self, other: T) {
356 self.x_ *= other.clone();
357 self.y_ *= other;
358 }
359 }
360
361 impl<T: Clone + NumAssign> DivAssign<T> for Vector2<T> {
362 fn div_assign(&mut self, other: T) {
363 self.x_ /= other.clone();
364 self.y_ /= other;
365 }
366 }
367
368 macro_rules! forward_op_assign1 {
369 (impl $imp:ident, $method:ident) => {
370 impl<'a, T: Clone + NumAssign> $imp<&'a Vector2<T>> for Vector2<T> {
371 #[inline]
372 fn $method(&mut self, other: &Self) {
373 self.$method(other.clone())
374 }
375 }
376 };
377 }
378
379 macro_rules! forward_op_assign2 {
380 (impl $imp:ident, $method:ident) => {
381 impl<'a, T: Clone + NumAssign> $imp<&'a T> for Vector2<T> {
382 #[inline]
383 fn $method(&mut self, other: &T) {
384 self.$method(other.clone())
385 }
386 }
387 };
388 }
389
390 forward_op_assign1!(impl AddAssign, add_assign);
391 forward_op_assign1!(impl SubAssign, sub_assign);
392 forward_op_assign2!(impl MulAssign, mul_assign);
393 forward_op_assign2!(impl DivAssign, div_assign);
394}
395
396impl<T: Clone + Num + Neg<Output = T>> Neg for Vector2<T> {
400 type Output = Self;
401
402 #[inline]
403 fn neg(self) -> Self::Output {
404 Self::Output::new(-self.x_, -self.y_)
405 }
406}
407
408impl<T: Clone + Num + Neg<Output = T>> Neg for &Vector2<T> {
412 type Output = Vector2<T>;
413
414 #[inline]
415 fn neg(self) -> Self::Output {
416 -self.clone()
417 }
418}
419
420macro_rules! scalar_arithmetic {
421 (@forward $imp:ident::$method:ident for $($scalar:ident),*) => (
422 impl<'a, T: Clone + Num> $imp<&'a T> for Vector2<T> {
423 type Output = Vector2<T>;
424
425 #[inline]
426 fn $method(self, other: &T) -> Self::Output {
427 self.$method(other.clone())
428 }
429 }
430 impl<'a, T: Clone + Num> $imp<T> for &'a Vector2<T> {
431 type Output = Vector2<T>;
432
433 #[inline]
434 fn $method(self, other: T) -> Self::Output {
435 self.clone().$method(other)
436 }
437 }
438 impl<'a, 'b, T: Clone + Num> $imp<&'a T> for &'b Vector2<T> {
439 type Output = Vector2<T>;
440
441 #[inline]
442 fn $method(self, other: &T) -> Self::Output {
443 self.clone().$method(other.clone())
444 }
445 }
446 $(
447 impl<'a> $imp<&'a Vector2<$scalar>> for $scalar {
448 type Output = Vector2<$scalar>;
449
450 #[inline]
451 fn $method(self, other: &Vector2<$scalar>) -> Vector2<$scalar> {
452 self.$method(other.clone())
453 }
454 }
455 impl<'a> $imp<Vector2<$scalar>> for &'a $scalar {
456 type Output = Vector2<$scalar>;
457
458 #[inline]
459 fn $method(self, other: Vector2<$scalar>) -> Vector2<$scalar> {
460 self.clone().$method(other)
461 }
462 }
463 impl<'a, 'b> $imp<&'a Vector2<$scalar>> for &'b $scalar {
464 type Output = Vector2<$scalar>;
465
466 #[inline]
467 fn $method(self, other: &Vector2<$scalar>) -> Vector2<$scalar> {
468 self.clone().$method(other.clone())
469 }
470 }
471 )*
472 );
473 ($($scalar:ident),*) => (
474 scalar_arithmetic!(@forward Mul::mul for $($scalar),*);
475 $(
479 impl Mul<Vector2<$scalar>> for $scalar {
480 type Output = Vector2<$scalar>;
481
482 #[inline]
483 fn mul(self, other: Vector2<$scalar>) -> Self::Output {
484 Self::Output::new(self * other.x_, self * other.y_)
485 }
486 }
487
488 )*
489 );
490}
491
492impl<T: Clone + Num> Mul<T> for Vector2<T> {
496 type Output = Vector2<T>;
497
498 #[inline]
499 fn mul(self, other: T) -> Self::Output {
500 Self::Output::new(self.x_ * other.clone(), self.y_ * other)
501 }
502}
503
504impl<T: Clone + Num> Div<T> for Vector2<T> {
508 type Output = Self;
509
510 #[inline]
511 fn div(self, other: T) -> Self::Output {
512 Self::Output::new(self.x_ / other.clone(), self.y_ / other)
513 }
514}
515
516impl<T: Clone + Num> Rem<T> for Vector2<T> {
520 type Output = Vector2<T>;
521
522 #[inline]
523 fn rem(self, other: T) -> Self::Output {
524 Self::Output::new(self.x_ % other.clone(), self.y_ % other)
525 }
526}
527
528scalar_arithmetic!(usize, u8, u16, u32, u64, u128, isize, i8, i16, i32, i64, i128, f32, f64);
529
530impl<T: Clone + Num> Zero for Vector2<T> {
532 #[inline]
536 fn zero() -> Self {
537 Self::new(Zero::zero(), Zero::zero())
538 }
539
540 #[inline]
544 fn is_zero(&self) -> bool {
545 self.x_.is_zero() && self.y_.is_zero()
546 }
547
548 #[inline]
549 fn set_zero(&mut self) {
550 self.x_.set_zero();
551 self.y_.set_zero();
552 }
553}
554
555#[cfg(test)]
565mod test {
566 #![allow(non_upper_case_globals)]
567
568 use super::Vector2;
570 use core::f64;
571 use num_traits::Zero;
572
573 pub const _0_0v: Vector2<f64> = Vector2 { x_: 0.0, y_: 0.0 };
574 pub const _1_0v: Vector2<f64> = Vector2 { x_: 1.0, y_: 0.0 };
575 pub const _1_1v: Vector2<f64> = Vector2 { x_: 1.0, y_: 1.0 };
576 pub const _0_1v: Vector2<f64> = Vector2 { x_: 0.0, y_: 1.0 };
577 pub const _neg1_1v: Vector2<f64> = Vector2 { x_: -1.0, y_: 1.0 };
578 pub const _05_05v: Vector2<f64> = Vector2 { x_: 0.5, y_: 0.5 };
579 pub const all_consts: [Vector2<f64>; 5] = [_0_0v, _1_0v, _1_1v, _neg1_1v, _05_05v];
580 pub const _4_2v: Vector2<f64> = Vector2 { x_: 4.0, y_: 2.0 };
581
582 #[test]
583 fn test_consts() {
584 fn test(c: Vector2<f64>, r: f64, i: f64) {
586 assert_eq!(c, Vector2::new(r, i));
587 }
588 test(_0_0v, 0.0, 0.0);
589 test(_1_0v, 1.0, 0.0);
590 test(_1_1v, 1.0, 1.0);
591 test(_neg1_1v, -1.0, 1.0);
592 test(_05_05v, 0.5, 0.5);
593 assert_eq!(_0_0v, Zero::zero());
594 }
595
596 #[test]
597 fn test_scale_unscale() {
598 assert_eq!(_05_05v.scale(2.0), _1_1v);
599 assert_eq!(_1_1v.unscale(2.0), _05_05v);
600 for &c in all_consts.iter() {
601 assert_eq!(c.scale(2.0).unscale(2.0), c);
602 }
603 }
604
605 #[test]
616 fn test_new() {
617 let v = Vector2::new(1, 2);
618 assert_eq!(v.x_, 1);
619 assert_eq!(v.y_, 2);
620 }
621
622 #[test]
623 fn test_dot() {
624 let v1 = Vector2::new(3, 4);
625 let v2 = Vector2::new(5, 6);
626 assert_eq!(v1.dot(&v2), 3 * 5 + 4 * 6);
627 assert_eq!(v1.dot(&v1), 3 * 3 + 4 * 4);
628 }
629
630 #[test]
631 fn test_cross() {
632 let v1 = Vector2::new(3, 4);
633 let v2 = Vector2::new(5, 6);
634 assert_eq!(v1.cross(&v2), 3 * 6 - 4 * 5);
635 assert_eq!(v1.cross(&v1), 0);
636 }
637
638 #[test]
639 fn test_norm_sqr() {
640 let v = Vector2::new(3, 4);
641 assert_eq!(v.norm_sqr(), 9 + 16);
642 }
643
644 #[test]
645 fn test_scale() {
646 let v = Vector2::new(3.0, 4.0);
647 assert_eq!(v.scale(2.0), Vector2::new(6.0, 8.0));
648 assert_eq!(v.scale(0.5), Vector2::new(1.5, 2.0));
649 }
650
651 #[test]
652 fn test_unscale() {
653 let v = Vector2::new(30, 40);
654 assert_eq!(v.unscale(10), Vector2::new(3, 4));
655 }
656
657 #[test]
658 fn test_l1_norm() {
659 let v = Vector2::new(3, -4);
660 assert_eq!(v.l1_norm(), 7);
661 }
662
663 #[test]
664 fn test_norm_inf() {
665 let v1 = Vector2::new(3, -4);
666 assert_eq!(v1.norm_inf(), 4);
667
668 let v2 = Vector2::new(5, 2);
669 assert_eq!(v2.norm_inf(), 5);
670
671 let v3 = Vector2::new(-7, -2);
672 assert_eq!(v3.norm_inf(), 7);
673 }
674
675 #[test]
676 fn test_add() {
677 let v1 = Vector2::new(1, 2);
678 let v2 = Vector2::new(3, 4);
679 assert_eq!(v1 + v2, Vector2::new(4, 6));
680
681 let v3 = v1 + v2;
682 assert_eq!(v3, Vector2::new(4, 6));
683
684 let v4 = v1 + v2;
685 assert_eq!(v4, Vector2::new(4, 6));
686 }
687
688 #[test]
689 fn test_sub() {
690 let v1 = Vector2::new(5, 6);
691 let v2 = Vector2::new(3, 4);
692 assert_eq!(v1 - v2, Vector2::new(2, 2));
693
694 let v3 = v1 - v2;
695 assert_eq!(v3, Vector2::new(2, 2));
696 }
697
698 #[test]
699 fn test_neg() {
700 let v = Vector2::new(1, -2);
701 assert_eq!(-v, Vector2::new(-1, 2));
702 assert_eq!(-&v, Vector2::new(-1, 2));
703 }
704
705 #[test]
706 fn test_scalar_mul() {
707 let v = Vector2::new(2, 3);
708 assert_eq!(v * 4, Vector2::new(8, 12));
709 assert_eq!(&v * 4, Vector2::new(8, 12));
710 assert_eq!(4 * v, Vector2::new(8, 12));
711 assert_eq!(4 * &v, Vector2::new(8, 12));
712 }
713
714 #[test]
715 fn test_scalar_div() {
716 let v = Vector2::new(10, 20);
717 assert_eq!(v / 5, Vector2::new(2, 4));
718 }
719
720 #[test]
721 fn test_scalar_rem() {
722 let v = Vector2::new(10, 21);
723 assert_eq!(v % 3, Vector2::new(1, 0));
724 }
725
726 #[test]
727 fn test_zero() {
728 let zero = Vector2::<i32>::zero();
729 assert_eq!(zero, Vector2::new(0, 0));
730 assert!(zero.is_zero());
731
732 let mut v = Vector2::new(1, 2);
733 assert!(!v.is_zero());
734 v.set_zero();
735 assert!(v.is_zero());
736 }
737
738 #[test]
739 fn test_add_assign() {
740 let mut v1 = Vector2::new(1, 2);
741 let v2 = Vector2::new(3, 4);
742 v1 += v2;
743 assert_eq!(v1, Vector2::new(4, 6));
744
745 let mut v3 = Vector2::new(1, 2);
746 v3 += &v2;
747 assert_eq!(v3, Vector2::new(4, 6));
748 }
749
750 #[test]
751 fn test_sub_assign() {
752 let mut v1 = Vector2::new(5, 6);
753 let v2 = Vector2::new(3, 4);
754 v1 -= v2;
755 assert_eq!(v1, Vector2::new(2, 2));
756
757 let mut v3 = Vector2::new(5, 6);
758 v3 -= &v2;
759 assert_eq!(v3, Vector2::new(2, 2));
760 }
761
762 #[test]
763 fn test_mul_assign() {
764 let mut v = Vector2::new(1, 2);
765 v *= 3;
766 assert_eq!(v, Vector2::new(3, 6));
767
768 let mut v2 = Vector2::new(1, 2);
769 let scalar = 3;
770 v2 *= &scalar;
771 assert_eq!(v2, Vector2::new(3, 6));
772 }
773
774 #[test]
775 fn test_div_assign() {
776 let mut v = Vector2::new(6, 9);
777 v /= 3;
778 assert_eq!(v, Vector2::new(2, 3));
779
780 let mut v2 = Vector2::new(6, 9);
781 let scalar = 3;
782 v2 /= &scalar;
783 assert_eq!(v2, Vector2::new(2, 3));
784 }
785
786 #[test]
787 fn test_float_operations() {
788 let v = Vector2::new(1.5, 2.5);
789 assert_eq!(v.scale(2.0), Vector2::new(3.0, 5.0));
790 assert_eq!(v.unscale(0.5), Vector2::new(3.0, 5.0));
791 assert_eq!(v.dot(&v), 1.5 * 1.5 + 2.5 * 2.5);
792 }
793
794 #[test]
795 fn test_clone_and_eq() {
796 let v1 = Vector2::new(1, 2);
797 let v2 = v1;
798 assert_eq!(v1, v2);
799
800 let v3 = Vector2::new(2, 1);
801 assert_ne!(v1, v3);
802 }
803
804 #[test]
805 fn test_debug() {
806 let v = Vector2::new(1, 2);
807 assert_eq!(format!("{:?}", v), "Vector2 { x_: 1, y_: 2 }");
808 }
809
810 #[test]
811 fn test_forward_xf_val_binop() {
812 let v1 = Vector2::new(1, 2);
813 let v2 = Vector2::new(3, 4);
814 let result: Vector2<i32> = v1 + v2;
815 assert_eq!(result, Vector2::new(4, 6));
816 }
817
818 #[test]
819 fn test_forward_val_xf_binop() {
820 let v1 = Vector2::new(1, 2);
821 let v2 = Vector2::new(3, 4);
822 let result: Vector2<i32> = v1 + v2;
823 assert_eq!(result, Vector2::new(4, 6));
824 }
825
826 #[test]
827 fn test_scalar_arithmetic_forward() {
828 let v = Vector2::new(2, 3);
829 let scalar = 5;
830 let result: Vector2<i32> = v * scalar;
831 assert_eq!(result, Vector2::new(10, 15));
832
833 let result2: Vector2<i32> = v * scalar;
834 assert_eq!(result2, Vector2::new(10, 15));
835
836 let result3: Vector2<i32> = 5 * &v;
837 assert_eq!(result3, Vector2::new(10, 15));
838 }
839
840 #[test]
841 fn test_scalar_left_mul() {
842 let v = Vector2::new(2, 3);
843 assert_eq!(5 * v, Vector2::new(10, 15));
844 assert_eq!(5 * &v, Vector2::new(10, 15));
845 }
846}
847
848#[cfg(test)]
849mod proptest {
850 use proptest::prelude::*;
851
852 use crate::Vector2;
853
854 const I32_BOUND: i32 = i32::MAX >> 8;
855
856 proptest! {
857 #[test]
858 fn test_add_commutative(a in -I32_BOUND..I32_BOUND, b in -I32_BOUND..I32_BOUND,
859 c in -I32_BOUND..I32_BOUND, d in -I32_BOUND..I32_BOUND) {
860 let v1 = Vector2::new(a, b);
861 let v2 = Vector2::new(c, d);
862 prop_assert_eq!(v1 + v2, v2 + v1);
863 }
864
865 #[test]
866 fn test_sub_anti_commutative(a in -I32_BOUND..I32_BOUND, b in -I32_BOUND..I32_BOUND,
867 c in -I32_BOUND..I32_BOUND, d in -I32_BOUND..I32_BOUND) {
868 let v1 = Vector2::new(a, b);
869 let v2 = Vector2::new(c, d);
870 prop_assert_eq!(-(v2 - v1), v1 - v2);
871 }
872
873 #[test]
874 fn test_mul_scalar_distributive(a in -1000..1000, b in -1000..1000, s in -100..100) {
875 let v = Vector2::new(a, b);
876 prop_assert_eq!(v * s, Vector2::new(a * s, b * s));
877 }
878
879 #[test]
880 fn test_scale_unscale_roundtrip(a in -1e10f64..1e10f64, b in -1e10f64..1e10f64,
881 s in -1e5f64..1e5f64) {
882 let s = if s.abs() < 1e-10 { 1.0 } else { s };
883 let v = Vector2::new(a, b);
884 let scaled = v.scale(s);
885 let unscaled = scaled.unscale(s);
886 prop_assert!((unscaled.x_ - a).abs() / a.abs() < 1e-10 || a.abs() < 1e-10);
887 prop_assert!((unscaled.y_ - b).abs() / b.abs() < 1e-10 || b.abs() < 1e-10);
888 }
889
890 #[test]
891 fn test_dot_commutative(a in -1000..1000, b in -1000..1000,
892 c in -1000..1000, d in -1000..1000) {
893 let v1 = Vector2::new(a, b);
894 let v2 = Vector2::new(c, d);
895 prop_assert_eq!(v1.dot(&v2), v2.dot(&v1));
896 }
897
898 #[test]
899 fn test_neg_involution(a in -I32_BOUND..I32_BOUND, b in -I32_BOUND..I32_BOUND) {
900 let v = Vector2::new(a, b);
901 prop_assert_eq!(-(-v), v);
902 }
903 }
904}