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