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