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)]
37#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
39pub struct Vector2<T1, T2> {
40 pub x_: T1,
42 pub y_: T2,
44}
45
46impl<T1, T2> Vector2<T1, T2> {
47 #[inline]
69 pub const fn new(x_: T1, y_: T2) -> Self {
70 Vector2 { x_, y_ }
71 }
72}
73
74impl<T1: Clone + Num> Vector2<T1, T1> {
75 #[inline]
95 pub fn dot(&self, other: &Self) -> T1 {
96 self.x_.clone() * other.x_.clone() + self.y_.clone() * other.y_.clone()
97 }
98
99 #[inline]
115 pub fn cross(&self, other: &Self) -> T1 {
116 self.x_.clone() * other.y_.clone() - self.y_.clone() * other.x_.clone()
117 }
118
119 #[inline]
145 pub fn scale(&self, factor: T1) -> Self {
146 Self::new(self.x_.clone() * factor.clone(), self.y_.clone() * factor)
147 }
148
149 #[inline]
171 pub fn unscale(&self, factor: T1) -> Self {
172 Self::new(self.x_.clone() / factor.clone(), self.y_.clone() / factor)
173 }
174}
175
176impl<T1: Clone + Signed> Vector2<T1, T1> {
177 #[inline]
195 pub fn l1_norm(&self) -> T1 {
196 self.x_.abs() + self.y_.abs()
197 }
198}
199
200impl<T1: Clone + PartialOrd> Vector2<T1, T1> {
201 #[inline]
217 pub fn norm_inf(&self) -> T1 {
218 if self.x_ > self.y_ {
219 self.x_.clone()
220 } else {
221 self.y_.clone()
222 }
223 }
224}
225
226impl<T1: Clone + Num, T2: Clone + Num> Add<Vector2<T1, T2>> for Vector2<T1, T2> {
228 type Output = Self;
229
230 #[inline]
247 fn add(self, other: Self) -> Self::Output {
248 Self::Output::new(self.x_ + other.x_, self.y_ + other.y_)
249 }
250}
251
252impl<T1: Clone + Num, T2: Clone + Num> Sub<Vector2<T1, T2>> for Vector2<T1, T2> {
254 type Output = Self;
255
256 #[inline]
273 fn sub(self, other: Self) -> Self::Output {
274 Self::Output::new(self.x_ - other.x_, self.y_ - other.y_)
275 }
276}
277
278mod opassign {
281 use core::ops::{AddAssign, DivAssign, MulAssign, SubAssign};
282
283 use num_traits::NumAssign;
284
285 use crate::Vector2;
286
287 impl<T1: Clone + NumAssign, T2: Clone + NumAssign> AddAssign for Vector2<T1, T2> {
288 fn add_assign(&mut self, other: Self) {
310 self.x_ += other.x_;
311 self.y_ += other.y_;
312 }
313 }
314
315 impl<T1: Clone + NumAssign, T2: Clone + NumAssign> SubAssign for Vector2<T1, T2> {
316 fn sub_assign(&mut self, other: Self) {
336 self.x_ -= other.x_;
337 self.y_ -= other.y_;
338 }
339 }
340
341 impl<T1: Clone + NumAssign> MulAssign<T1> for Vector2<T1, T1> {
342 fn mul_assign(&mut self, other: T1) {
360 self.x_ *= other.clone();
361 self.y_ *= other;
362 }
363 }
364
365 impl<T1: Clone + NumAssign> DivAssign<T1> for Vector2<T1, T1> {
366 fn div_assign(&mut self, other: T1) {
384 self.x_ /= other.clone();
385 self.y_ /= other;
386 }
387 }
388
389 macro_rules! forward_op_assign1 {
390 (impl $imp:ident, $method:ident) => {
391 impl<'a, T1: Clone + NumAssign, T2: Clone + NumAssign> $imp<&'a Vector2<T1, T2>>
392 for Vector2<T1, T2>
393 {
394 #[inline]
395 fn $method(&mut self, other: &Self) {
396 self.$method(other.clone())
397 }
398 }
399 };
400 }
401
402 macro_rules! forward_op_assign2 {
403 (impl $imp:ident, $method:ident) => {
404 impl<'a, T1: Clone + NumAssign> $imp<&'a T1> for Vector2<T1, T1> {
405 #[inline]
406 fn $method(&mut self, other: &T1) {
407 self.$method(other.clone())
408 }
409 }
410 };
411 }
412
413 forward_op_assign1!(impl AddAssign, add_assign);
414 forward_op_assign1!(impl SubAssign, sub_assign);
415 forward_op_assign2!(impl MulAssign, mul_assign);
416 forward_op_assign2!(impl DivAssign, div_assign);
417}
418
419impl<T1: Clone + Num + Neg<Output = T1>, T2: Clone + Num + Neg<Output = T2>> Neg
420 for Vector2<T1, T2>
421{
422 type Output = Self;
423
424 #[inline]
437 fn neg(self) -> Self::Output {
438 Self::Output::new(-self.x_, -self.y_)
439 }
440}
441
442impl<T1: Clone + Num + Neg<Output = T1>, T2: Clone + Num + Neg<Output = T2>> Neg
443 for &Vector2<T1, T2>
444{
445 type Output = Vector2<T1, T2>;
446
447 #[inline]
448 fn neg(self) -> Self::Output {
449 -self.clone()
450 }
451}
452
453macro_rules! scalar_arithmetic {
454 (@forward $imp:ident::$method:ident for $($scalar:ident),*) => (
455 impl<'a, T1: Clone + Num> $imp<&'a T1> for Vector2<T1, T1> {
456 type Output = Vector2<T1, T1>;
457
458 #[inline]
459 fn $method(self, other: &T1) -> Self::Output {
460 self.$method(other.clone())
461 }
462 }
463 impl<'a, T1: Clone + Num> $imp<T1> for &'a Vector2<T1, T1> {
464 type Output = Vector2<T1, T1>;
465
466 #[inline]
467 fn $method(self, other: T1) -> Self::Output {
468 self.clone().$method(other)
469 }
470 }
471 impl<'a, 'b, T1: Clone + Num> $imp<&'a T1> for &'b Vector2<T1, T1> {
472 type Output = Vector2<T1, T1>;
473
474 #[inline]
475 fn $method(self, other: &T1) -> Self::Output {
476 self.clone().$method(other.clone())
477 }
478 }
479 $(
480 impl<'a> $imp<&'a Vector2<$scalar, $scalar>> for $scalar {
481 type Output = Vector2<$scalar, $scalar>;
482
483 #[inline]
484 fn $method(self, other: &Vector2<$scalar, $scalar>) -> Vector2<$scalar, $scalar> {
485 self.$method(other.clone())
486 }
487 }
488 impl<'a> $imp<Vector2<$scalar, $scalar>> for &'a $scalar {
489 type Output = Vector2<$scalar, $scalar>;
490
491 #[inline]
492 fn $method(self, other: Vector2<$scalar, $scalar>) -> Vector2<$scalar, $scalar> {
493 self.clone().$method(other)
494 }
495 }
496 impl<'a, 'b> $imp<&'a Vector2<$scalar, $scalar>> for &'b $scalar {
497 type Output = Vector2<$scalar, $scalar>;
498
499 #[inline]
500 fn $method(self, other: &Vector2<$scalar, $scalar>) -> Vector2<$scalar, $scalar> {
501 self.clone().$method(other.clone())
502 }
503 }
504 )*
505 );
506 ($($scalar:ident),*) => (
507 scalar_arithmetic!(@forward Mul::mul for $($scalar),*);
508 $(
512 impl Mul<Vector2<$scalar, $scalar>> for $scalar {
513 type Output = Vector2<$scalar, $scalar>;
514
515 #[inline]
516 fn mul(self, other: Vector2<$scalar, $scalar>) -> Self::Output {
517 Self::Output::new(self * other.x_, self * other.y_)
518 }
519 }
520
521 )*
522 );
523}
524
525impl<T1: Clone + Num> Mul<T1> for Vector2<T1, T1> {
526 type Output = Vector2<T1, T1>;
527
528 #[inline]
529 fn mul(self, other: T1) -> Self::Output {
530 Self::Output::new(self.x_ * other.clone(), self.y_ * other)
531 }
532}
533
534impl<T1: Clone + Num> Div<T1> for Vector2<T1, T1> {
535 type Output = Self;
536
537 #[inline]
538 fn div(self, other: T1) -> Self::Output {
539 Self::Output::new(self.x_ / other.clone(), self.y_ / other)
540 }
541}
542
543impl<T1: Clone + Num> Rem<T1> for Vector2<T1, T1> {
544 type Output = Vector2<T1, T1>;
545
546 #[inline]
547 fn rem(self, other: T1) -> Self::Output {
548 Self::Output::new(self.x_ % other.clone(), self.y_ % other)
549 }
550}
551
552scalar_arithmetic!(usize, u8, u16, u32, u64, u128, isize, i8, i16, i32, i64, i128, f32, f64);
553
554impl<T1: Clone + Num + Add, T2: Clone + Num + Add> Zero for Vector2<T1, T2> {
556 #[inline]
557 fn zero() -> Self {
558 Self::new(Zero::zero(), Zero::zero())
559 }
560
561 #[inline]
562 fn is_zero(&self) -> bool {
563 self.x_.is_zero() && self.y_.is_zero()
564 }
565
566 #[inline]
567 fn set_zero(&mut self) {
568 self.x_.set_zero();
569 self.y_.set_zero();
570 }
571}
572
573#[cfg(test)]
574mod test {
575 #![allow(non_upper_case_globals)]
576
577 use super::Vector2;
578 use core::f64;
579 use num_traits::Zero;
580 use std::hash;
581
582 fn hash<T: hash::Hash>(item: &T) -> u64 {
583 use std::collections::hash_map::RandomState;
584 use std::hash::{BuildHasher, Hasher};
585 let mut hasher = <RandomState as BuildHasher>::Hasher::new();
586 item.hash(&mut hasher);
587 hasher.finish()
588 }
589
590 pub const _0_0v: Vector2<f64, f64> = Vector2 { x_: 0.0, y_: 0.0 };
591 pub const _1_0v: Vector2<f64, f64> = Vector2 { x_: 1.0, y_: 0.0 };
592 pub const _1_1v: Vector2<f64, f64> = Vector2 { x_: 1.0, y_: 1.0 };
593 pub const _0_1v: Vector2<f64, f64> = Vector2 { x_: 0.0, y_: 1.0 };
594 pub const _neg1_1v: Vector2<f64, f64> = Vector2 { x_: -1.0, y_: 1.0 };
595 pub const _05_05v: Vector2<f64, f64> = Vector2 { x_: 0.5, y_: 0.5 };
596 pub const all_consts: [Vector2<f64, f64>; 5] = [_0_0v, _1_0v, _1_1v, _neg1_1v, _05_05v];
597 pub const _4_2v: Vector2<f64, f64> = Vector2 { x_: 4.0, y_: 2.0 };
598
599 pub const _0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
600 x_: _0_0v,
601 y_: _0_0v,
602 };
603
604 pub const _0_0_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
606 x_: _0_0v,
607 y_: _0_0v,
608 };
609 pub const _1_0_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
610 x_: _1_0v,
611 y_: _0_0v,
612 };
613 pub const _1_1_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
614 x_: _1_1v,
615 y_: _0_0v,
616 };
617 pub const _0_1_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
618 x_: _0_1v,
619 y_: _0_0v,
620 };
621 pub const _neg1_1_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
622 x_: _neg1_1v,
623 y_: _0_0v,
624 };
625 pub const _05_05_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
626 x_: _05_05v,
627 y_: _0_0v,
628 };
629 pub const _0_0_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
630 x_: _0_0v,
631 y_: _1_0v,
632 };
633 pub const _1_0_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
634 x_: _1_0v,
635 y_: _1_0v,
636 };
637 pub const _1_1_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
638 x_: _1_1v,
639 y_: _1_0v,
640 };
641 pub const _0_1_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
642 x_: _0_1v,
643 y_: _1_0v,
644 };
645 pub const _neg1_1_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
646 x_: _neg1_1v,
647 y_: _1_0v,
648 };
649 pub const _05_05_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
650 x_: _05_05v,
651 y_: _1_0v,
652 };
653 pub const _0_0_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
654 x_: _0_0v,
655 y_: _0_1v,
656 };
657 pub const _1_0_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
658 x_: _1_0v,
659 y_: _0_1v,
660 };
661 pub const _1_1_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
662 x_: _1_1v,
663 y_: _0_1v,
664 };
665 pub const _0_1_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
666 x_: _0_1v,
667 y_: _0_1v,
668 };
669 pub const _neg1_1_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
670 x_: _neg1_1v,
671 y_: _0_1v,
672 };
673 pub const _05_05_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
674 x_: _05_05v,
675 y_: _0_1v,
676 };
677
678 #[test]
679 fn test_consts() {
680 fn test(vec: Vector2<f64, f64>, x_val: f64, y_val: f64) {
682 assert_eq!(vec, Vector2::new(x_val, y_val));
683 }
684 test(_0_0v, 0.0, 0.0);
685 test(_1_0v, 1.0, 0.0);
686 test(_1_1v, 1.0, 1.0);
687 test(_neg1_1v, -1.0, 1.0);
688 test(_05_05v, 0.5, 0.5);
689 assert_eq!(_0_0v, Zero::zero());
690 }
691
692 #[test]
693 fn test_scale_unscale() {
694 assert_eq!(_05_05v.scale(2.0), _1_1v);
695 assert_eq!(_1_1v.unscale(2.0), _05_05v);
696 for &c in all_consts.iter() {
697 assert_eq!(c.scale(2.0).unscale(2.0), c);
698 }
699 }
700
701 #[test]
702 fn test_hash() {
703 let vec_a = Vector2::new(0i32, 0i32);
704 let vec_b = Vector2::new(1i32, 0i32);
705 let vec_c = Vector2::new(0i32, 1i32);
706 assert!(hash(&vec_a) != hash(&vec_b));
707 assert!(hash(&vec_b) != hash(&vec_c));
708 assert!(hash(&vec_c) != hash(&vec_a));
709 }
710
711 #[test]
712 fn test_zero() {
713 assert_eq!(_0_0v, Vector2::zero());
714 }
715
716 #[test]
717 fn test_is_zero() {
718 assert!(Vector2::<i32, i32>::zero().is_zero());
719 assert!(!_1_1v.is_zero());
720 }
721
722 #[test]
723 fn test_set_zero() {
724 let mut v = _1_1v;
725 v.set_zero();
726 assert!(v.is_zero());
727 }
728
729 #[test]
730 fn test_neg() {
731 assert_eq!(-(-_1_1v), _1_1v);
732 }
733
734 #[test]
735 fn test_scalar_arithmetic() {
736 assert_eq!(_1_1v * 0.5, _05_05v);
737 assert_eq!(_1_1v / 2.0, _05_05v);
738 assert_eq!(_4_2v % 2.0, _0_0v);
739 assert_eq!(0.5 * _1_1v, _05_05v);
740 }
741
742 #[test]
743 fn test_scalar_arithmetic_ref() {
744 assert_eq!(_1_1v * 0.5, _05_05v);
745 assert_eq!(0.5 * _1_1v, _05_05v);
746 }
747
748 #[test]
749 fn test_dot() {
750 assert_eq!(_1_1v.dot(&_1_1v), 2.0);
751 assert_eq!(_1_1v.dot(&_neg1_1v), 0.0);
752 assert_eq!(_1_1v.dot(&_0_1v), 1.0);
753 }
754
755 #[test]
756 fn test_cross() {
757 assert_eq!(_1_1v.cross(&_1_1v), 0.0);
758 assert_eq!(_1_1v.cross(&_neg1_1v), 2.0);
759 assert_eq!(_1_1v.cross(&_0_1v), 1.0);
760 }
761
762 #[test]
774 fn test_l1_norm() {
775 assert_eq!(_1_1v.l1_norm(), 2.0);
776 assert_eq!(_0_1v.l1_norm(), 1.0);
777 assert_eq!(_neg1_1v.l1_norm(), 2.0);
778 assert_eq!(_05_05v.l1_norm(), 1.0);
779 assert_eq!(_1_0v.l1_norm(), 1.0);
780 assert_eq!(_0_0v.l1_norm(), 0.0);
781 assert_eq!(_4_2v.l1_norm(), 6.0);
782 }
783
784 #[test]
785 fn test_norm_inf() {
786 assert_eq!(_1_1v.norm_inf(), 1.0);
787 assert_eq!(_0_1v.norm_inf(), 1.0);
788 assert_eq!(_neg1_1v.norm_inf(), 1.0);
789 assert_eq!(_05_05v.norm_inf(), 0.5);
790 assert_eq!(_1_0v.norm_inf(), 1.0);
791 assert_eq!(_0_0v.norm_inf(), 0.0);
792 assert_eq!(_4_2v.norm_inf(), 4.0);
793 }
794
795 #[test]
796 fn test_add_assign() {
797 let mut vec_a = _0_1v;
798 vec_a += _1_0v;
799 assert_eq!(vec_a, _1_1v);
800 }
801
802 #[test]
803 fn test_sub_assign() {
804 let mut vec_a = _1_1v;
805 vec_a -= _1_1v;
806 assert_eq!(vec_a, _0_0v);
807 }
808
809 #[test]
810 fn test_mul_assign() {
811 let mut vec_a = _05_05v;
812 vec_a *= 2.0;
813 assert_eq!(vec_a, _1_1v);
814 }
815
816 #[test]
817 fn test_div_assign() {
818 let mut vec_a = _1_1v;
819 vec_a /= 2.0;
820 assert_eq!(vec_a, _05_05v);
821 }
822
823 #[test]
824 fn test_rem() {
825 assert_eq!(_4_2v % 3.0, Vector2::new(1.0, 2.0));
826 }
827
828 #[test]
829 fn test_sub_more() {
830 assert_eq!(_1_1v - _0_1v, _1_0v);
831 assert_eq!(_0_1v - _1_0v, Vector2::new(-1.0, 1.0));
832 }
833
834 #[test]
835 fn test_add_more() {
836 assert_eq!(_1_0v + _0_1v, _1_1v);
837 }
838
839 #[test]
840 fn test_mul_more() {
841 assert_eq!(_1_1v * 2.0, Vector2::new(2.0, 2.0));
842 }
843
844 #[test]
845 fn test_dot_more_cases() {
846 assert_eq!(_0_0v.dot(&_1_1v), 0.0);
847 assert_eq!(_1_1v.dot(&_0_0v), 0.0);
848 assert_eq!(_neg1_1v.dot(&_1_1v), 0.0);
849 }
850
851 #[test]
852 fn test_cross_more_cases() {
853 assert_eq!(_0_0v.cross(&_1_1v), 0.0);
854 assert_eq!(_1_1v.cross(&_0_0v), 0.0);
855 assert_eq!(_neg1_1v.cross(&_1_1v), -2.0);
856 }
857
858 #[test]
859 fn test_l1_norm_more_cases() {
860 assert_eq!(_0_0v.l1_norm(), 0.0);
861 assert_eq!(_neg1_1v.l1_norm(), 2.0);
862 }
863
864 #[test]
865 fn test_norm_inf_more_cases() {
866 assert_eq!(_0_0v.norm_inf(), 0.0);
867 assert_eq!(_neg1_1v.norm_inf(), 1.0);
868 }
869
870 #[test]
871 fn test_scalar_arithmetic_more_cases() {
872 assert_eq!(_0_0v * 2.0, _0_0v);
873 assert_eq!(_1_1v * 0.0, _0_0v);
874 assert_eq!(_1_1v * 1.0, _1_1v);
875 assert_eq!(_1_1v * -1.0, -_1_1v);
876 }
877
878 #[test]
879 fn test_consts_vv() {
880 fn test(
882 vec: Vector2<Vector2<f64, f64>, Vector2<f64, f64>>,
883 w_val: f64,
884 x_val: f64,
885 y_val: f64,
886 z_val: f64,
887 ) {
888 assert_eq!(
889 vec,
890 Vector2::new(Vector2::new(w_val, x_val), Vector2::new(y_val, z_val))
891 );
892 }
893
894 test(_0_0vv, 0.0, 0.0, 0.0, 0.0);
895 test(_0_0_0_0vv, 0.0, 0.0, 0.0, 0.0);
896 test(_1_0_0_0vv, 1.0, 0.0, 0.0, 0.0);
897 test(_1_1_0_0vv, 1.0, 1.0, 0.0, 0.0);
898 test(_0_1_0_0vv, 0.0, 1.0, 0.0, 0.0);
899 test(_neg1_1_0_0vv, -1.0, 1.0, 0.0, 0.0);
900 test(_05_05_0_0vv, 0.5, 0.5, 0.0, 0.0);
901 test(_0_0_1_0vv, 0.0, 0.0, 1.0, 0.0);
902 test(_1_0_1_0vv, 1.0, 0.0, 1.0, 0.0);
903 test(_1_1_1_0vv, 1.0, 1.0, 1.0, 0.0);
904 test(_0_1_1_0vv, 0.0, 1.0, 1.0, 0.0);
905 test(_neg1_1_1_0vv, -1.0, 1.0, 1.0, 0.0);
906 test(_05_05_1_0vv, 0.5, 0.5, 1.0, 0.0);
907 }
908
909 }
918
919#[test]
920fn test_neg_ref() {
921 let v = &Vector2::new(1, 2);
922 let neg_v = -v;
923 assert_eq!(neg_v, Vector2::new(-1, -2));
924}
925
926#[test]
927fn test_ref_add_assign_ref() {
928 let mut v1 = Vector2::new(1.0, 2.0);
929 let v2 = &Vector2::new(3.0, 4.0);
930 v1 += v2;
931 assert_eq!(v1, Vector2::new(4.0, 6.0));
932}
933
934#[test]
935fn test_ref_sub_assign_ref() {
936 let mut v1 = Vector2::new(5.0, 7.0);
937 let v2 = &Vector2::new(2.0, 3.0);
938 v1 -= v2;
939 assert_eq!(v1, Vector2::new(3.0, 4.0));
940}
941
942#[test]
943fn test_ref_mul_assign_ref() {
944 let mut v = Vector2::new(2.0, 3.0);
945 let scalar = &2.0;
946 v *= scalar;
947 assert_eq!(v, Vector2::new(4.0, 6.0));
948}
949
950#[test]
951fn test_ref_div_assign_ref() {
952 let mut v = Vector2::new(6.0, 8.0);
953 let scalar = &2.0;
954 v /= scalar;
955 assert_eq!(v, Vector2::new(3.0, 4.0));
956}
957
958#[test]
959fn test_mul_integer_types() {
960 let v = Vector2::new(2i32, 3i32);
961 assert_eq!(v * 2i32, Vector2::new(4, 6));
962
963 let v2 = Vector2::new(2u8, 3u8);
964 assert_eq!(v2 * 2u8, Vector2::new(4, 6));
965}
966
967#[test]
968fn test_neg_edge_cases() {
969 let v_zero = Vector2::new(0.0, 0.0);
970 assert_eq!(-v_zero, Vector2::new(-0.0, -0.0));
971
972 let v_neg = Vector2::new(-1.0, -2.0);
973 assert_eq!(-v_neg, Vector2::new(1.0, 2.0));
974}
975
976#[test]
977fn test_scalar_mul_i32_ref() {
978 let v = Vector2::new(2i32, 3i32);
979 let result = v * 2i32;
980 assert_eq!(result, Vector2::new(4, 6));
981}