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)]
30#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
32pub struct Vector2<T1, T2> {
33 pub x_: T1,
35 pub y_: T2,
37}
38
39impl<T1, T2> Vector2<T1, T2> {
40 #[inline]
51 pub const fn new(x_: T1, y_: T2) -> Self {
52 Vector2 { x_, y_ }
53 }
54}
55
56impl<T1: Clone + Num> Vector2<T1, T1> {
57 #[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]
87 pub fn cross(&self, other: &Self) -> T1 {
88 self.x_.clone() * other.y_.clone() - self.y_.clone() * other.x_.clone()
89 }
90
91 #[inline]
109 pub fn scale(&self, factor: T1) -> Self {
110 Self::new(self.x_.clone() * factor.clone(), self.y_.clone() * factor)
111 }
112
113 #[inline]
126 pub fn unscale(&self, factor: T1) -> Self {
127 Self::new(self.x_.clone() / factor.clone(), self.y_.clone() / factor)
128 }
129}
130
131impl<T1: Clone + Signed> Vector2<T1, T1> {
132 #[inline]
147 pub fn l1_norm(&self) -> T1 {
148 self.x_.abs() + self.y_.abs()
149 }
150}
151
152impl<T1: Clone + PartialOrd> Vector2<T1, T1> {
153 #[inline]
168 pub fn norm_inf(&self) -> T1 {
169 if self.x_ > self.y_ {
170 self.x_.clone()
171 } else {
172 self.y_.clone()
173 }
174 }
175}
176
177impl<T1: Clone + Num, T2: Clone + Num> Add<Vector2<T1, T2>> for Vector2<T1, T2> {
179 type Output = Self;
180
181 #[inline]
193 fn add(self, other: Self) -> Self::Output {
194 Self::Output::new(self.x_ + other.x_, self.y_ + other.y_)
195 }
196}
197
198impl<T1: Clone + Num, T2: Clone + Num> Sub<Vector2<T1, T2>> for Vector2<T1, T2> {
200 type Output = Self;
201
202 #[inline]
214 fn sub(self, other: Self) -> Self::Output {
215 Self::Output::new(self.x_ - other.x_, self.y_ - other.y_)
216 }
217}
218
219mod opassign {
222 use core::ops::{AddAssign, DivAssign, MulAssign, SubAssign};
223
224 use num_traits::NumAssign;
225
226 use crate::Vector2;
227
228 impl<T1: Clone + NumAssign, T2: Clone + NumAssign> AddAssign for Vector2<T1, T2> {
229 fn add_assign(&mut self, other: Self) {
245 self.x_ += other.x_;
246 self.y_ += other.y_;
247 }
248 }
249
250 impl<T1: Clone + NumAssign, T2: Clone + NumAssign> SubAssign for Vector2<T1, T2> {
251 fn sub_assign(&mut self, other: Self) {
266 self.x_ -= other.x_;
267 self.y_ -= other.y_;
268 }
269 }
270
271 impl<T1: Clone + NumAssign> MulAssign<T1> for Vector2<T1, T1> {
272 fn mul_assign(&mut self, other: T1) {
287 self.x_ *= other.clone();
288 self.y_ *= other;
289 }
290 }
291
292 impl<T1: Clone + NumAssign> DivAssign<T1> for Vector2<T1, T1> {
293 fn div_assign(&mut self, other: T1) {
308 self.x_ /= other.clone();
309 self.y_ /= other;
310 }
311 }
312
313 macro_rules! forward_op_assign1 {
314 (impl $imp:ident, $method:ident) => {
315 impl<'a, T1: Clone + NumAssign, T2: Clone + NumAssign> $imp<&'a Vector2<T1, T2>>
316 for Vector2<T1, T2>
317 {
318 #[inline]
319 fn $method(&mut self, other: &Self) {
320 self.$method(other.clone())
321 }
322 }
323 };
324 }
325
326 macro_rules! forward_op_assign2 {
327 (impl $imp:ident, $method:ident) => {
328 impl<'a, T1: Clone + NumAssign> $imp<&'a T1> for Vector2<T1, T1> {
329 #[inline]
330 fn $method(&mut self, other: &T1) {
331 self.$method(other.clone())
332 }
333 }
334 };
335 }
336
337 forward_op_assign1!(impl AddAssign, add_assign);
338 forward_op_assign1!(impl SubAssign, sub_assign);
339 forward_op_assign2!(impl MulAssign, mul_assign);
340 forward_op_assign2!(impl DivAssign, div_assign);
341}
342
343impl<T1: Clone + Num + Neg<Output = T1>, T2: Clone + Num + Neg<Output = T2>> Neg
344 for Vector2<T1, T2>
345{
346 type Output = Self;
347
348 #[inline]
361 fn neg(self) -> Self::Output {
362 Self::Output::new(-self.x_, -self.y_)
363 }
364}
365
366impl<T1: Clone + Num + Neg<Output = T1>, T2: Clone + Num + Neg<Output = T2>> Neg
367 for &Vector2<T1, T2>
368{
369 type Output = Vector2<T1, T2>;
370
371 #[inline]
375 fn neg(self) -> Self::Output {
376 -self.clone()
377 }
378}
379
380macro_rules! scalar_arithmetic {
381 (@forward $imp:ident::$method:ident for $($scalar:ident),*) => (
382 impl<'a, T1: Clone + Num> $imp<&'a T1> for Vector2<T1, T1> {
383 type Output = Vector2<T1, T1>;
384
385 #[inline]
386 fn $method(self, other: &T1) -> Self::Output {
387 self.$method(other.clone())
388 }
389 }
390 impl<'a, T1: Clone + Num> $imp<T1> for &'a Vector2<T1, T1> {
391 type Output = Vector2<T1, T1>;
392
393 #[inline]
394 fn $method(self, other: T1) -> Self::Output {
395 self.clone().$method(other)
396 }
397 }
398 impl<'a, 'b, T1: Clone + Num> $imp<&'a T1> for &'b Vector2<T1, T1> {
399 type Output = Vector2<T1, T1>;
400
401 #[inline]
402 fn $method(self, other: &T1) -> Self::Output {
403 self.clone().$method(other.clone())
404 }
405 }
406 $(
407 impl<'a> $imp<&'a Vector2<$scalar, $scalar>> for $scalar {
408 type Output = Vector2<$scalar, $scalar>;
409
410 #[inline]
411 fn $method(self, other: &Vector2<$scalar, $scalar>) -> Vector2<$scalar, $scalar> {
412 self.$method(other.clone())
413 }
414 }
415 impl<'a> $imp<Vector2<$scalar, $scalar>> for &'a $scalar {
416 type Output = Vector2<$scalar, $scalar>;
417
418 #[inline]
419 fn $method(self, other: Vector2<$scalar, $scalar>) -> Vector2<$scalar, $scalar> {
420 self.clone().$method(other)
421 }
422 }
423 impl<'a, 'b> $imp<&'a Vector2<$scalar, $scalar>> for &'b $scalar {
424 type Output = Vector2<$scalar, $scalar>;
425
426 #[inline]
427 fn $method(self, other: &Vector2<$scalar, $scalar>) -> Vector2<$scalar, $scalar> {
428 self.clone().$method(other.clone())
429 }
430 }
431 )*
432 );
433 ($($scalar:ident),*) => (
434 scalar_arithmetic!(@forward Mul::mul for $($scalar),*);
435 $(
439 impl Mul<Vector2<$scalar, $scalar>> for $scalar {
440 type Output = Vector2<$scalar, $scalar>;
441
442 #[inline]
443 fn mul(self, other: Vector2<$scalar, $scalar>) -> Self::Output {
444 Self::Output::new(self * other.x_, self * other.y_)
445 }
446 }
447
448 )*
449 );
450}
451
452impl<T1: Clone + Num> Mul<T1> for Vector2<T1, T1> {
453 type Output = Vector2<T1, T1>;
454
455 #[inline]
457 fn mul(self, other: T1) -> Self::Output {
458 Self::Output::new(self.x_ * other.clone(), self.y_ * other)
459 }
460}
461
462impl<T1: Clone + Num> Div<T1> for Vector2<T1, T1> {
463 type Output = Self;
464
465 #[inline]
467 fn div(self, other: T1) -> Self::Output {
468 Self::Output::new(self.x_ / other.clone(), self.y_ / other)
469 }
470}
471
472impl<T1: Clone + Num> Rem<T1> for Vector2<T1, T1> {
473 type Output = Vector2<T1, T1>;
474
475 #[inline]
477 fn rem(self, other: T1) -> Self::Output {
478 Self::Output::new(self.x_ % other.clone(), self.y_ % other)
479 }
480}
481
482scalar_arithmetic!(usize, u8, u16, u32, u64, u128, isize, i8, i16, i32, i64, i128, f32, f64);
483
484impl<T1: Clone + Num + Add, T2: Clone + Num + Add> Zero for Vector2<T1, T2> {
486 #[inline]
488 fn zero() -> Self {
489 Self::new(Zero::zero(), Zero::zero())
490 }
491
492 #[inline]
493 fn is_zero(&self) -> bool {
494 self.x_.is_zero() && self.y_.is_zero()
495 }
496
497 #[inline]
498 fn set_zero(&mut self) {
499 self.x_.set_zero();
500 self.y_.set_zero();
501 }
502}
503
504#[cfg(test)]
505mod test {
506 #![allow(non_upper_case_globals)]
507
508 use super::Vector2;
509 use core::f64;
510 use num_traits::Zero;
511 use std::hash;
512
513 fn hash<T: hash::Hash>(item: &T) -> u64 {
514 use std::collections::hash_map::RandomState;
515 use std::hash::{BuildHasher, Hasher};
516 let mut hasher = <RandomState as BuildHasher>::Hasher::new();
517 item.hash(&mut hasher);
518 hasher.finish()
519 }
520
521 pub const _0_0v: Vector2<f64, f64> = Vector2 { x_: 0.0, y_: 0.0 };
522 pub const _1_0v: Vector2<f64, f64> = Vector2 { x_: 1.0, y_: 0.0 };
523 pub const _1_1v: Vector2<f64, f64> = Vector2 { x_: 1.0, y_: 1.0 };
524 pub const _0_1v: Vector2<f64, f64> = Vector2 { x_: 0.0, y_: 1.0 };
525 pub const _neg1_1v: Vector2<f64, f64> = Vector2 { x_: -1.0, y_: 1.0 };
526 pub const _05_05v: Vector2<f64, f64> = Vector2 { x_: 0.5, y_: 0.5 };
527 pub const all_consts: [Vector2<f64, f64>; 5] = [_0_0v, _1_0v, _1_1v, _neg1_1v, _05_05v];
528 pub const _4_2v: Vector2<f64, f64> = Vector2 { x_: 4.0, y_: 2.0 };
529
530 pub const _0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
531 x_: _0_0v,
532 y_: _0_0v,
533 };
534
535 pub const _0_0_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
537 x_: _0_0v,
538 y_: _0_0v,
539 };
540 pub const _1_0_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
541 x_: _1_0v,
542 y_: _0_0v,
543 };
544 pub const _1_1_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
545 x_: _1_1v,
546 y_: _0_0v,
547 };
548 pub const _0_1_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
549 x_: _0_1v,
550 y_: _0_0v,
551 };
552 pub const _neg1_1_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
553 x_: _neg1_1v,
554 y_: _0_0v,
555 };
556 pub const _05_05_0_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
557 x_: _05_05v,
558 y_: _0_0v,
559 };
560 pub const _0_0_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
561 x_: _0_0v,
562 y_: _1_0v,
563 };
564 pub const _1_0_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
565 x_: _1_0v,
566 y_: _1_0v,
567 };
568 pub const _1_1_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
569 x_: _1_1v,
570 y_: _1_0v,
571 };
572 pub const _0_1_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
573 x_: _0_1v,
574 y_: _1_0v,
575 };
576 pub const _neg1_1_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
577 x_: _neg1_1v,
578 y_: _1_0v,
579 };
580 pub const _05_05_1_0vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
581 x_: _05_05v,
582 y_: _1_0v,
583 };
584 pub const _0_0_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
585 x_: _0_0v,
586 y_: _0_1v,
587 };
588 pub const _1_0_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
589 x_: _1_0v,
590 y_: _0_1v,
591 };
592 pub const _1_1_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
593 x_: _1_1v,
594 y_: _0_1v,
595 };
596 pub const _0_1_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
597 x_: _0_1v,
598 y_: _0_1v,
599 };
600 pub const _neg1_1_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
601 x_: _neg1_1v,
602 y_: _0_1v,
603 };
604 pub const _05_05_0_1vv: Vector2<Vector2<f64, f64>, Vector2<f64, f64>> = Vector2 {
605 x_: _05_05v,
606 y_: _0_1v,
607 };
608
609 #[test]
610 fn test_consts() {
611 fn test(vec: Vector2<f64, f64>, x_val: f64, y_val: f64) {
613 assert_eq!(vec, Vector2::new(x_val, y_val));
614 }
615 test(_0_0v, 0.0, 0.0);
616 test(_1_0v, 1.0, 0.0);
617 test(_1_1v, 1.0, 1.0);
618 test(_neg1_1v, -1.0, 1.0);
619 test(_05_05v, 0.5, 0.5);
620 assert_eq!(_0_0v, Zero::zero());
621 }
622
623 #[test]
624 fn test_scale_unscale() {
625 assert_eq!(_05_05v.scale(2.0), _1_1v);
626 assert_eq!(_1_1v.unscale(2.0), _05_05v);
627 for &c in all_consts.iter() {
628 assert_eq!(c.scale(2.0).unscale(2.0), c);
629 }
630 }
631
632 #[test]
633 fn test_hash() {
634 let vec_a = Vector2::new(0i32, 0i32);
635 let vec_b = Vector2::new(1i32, 0i32);
636 let vec_c = Vector2::new(0i32, 1i32);
637 assert!(hash(&vec_a) != hash(&vec_b));
638 assert!(hash(&vec_b) != hash(&vec_c));
639 assert!(hash(&vec_c) != hash(&vec_a));
640 }
641
642 #[test]
643 fn test_zero() {
644 assert_eq!(_0_0v, Vector2::zero());
645 }
646
647 #[test]
648 fn test_is_zero() {
649 assert!(Vector2::<i32, i32>::zero().is_zero());
650 assert!(!_1_1v.is_zero());
651 }
652
653 #[test]
654 fn test_set_zero() {
655 let mut v = _1_1v;
656 v.set_zero();
657 assert!(v.is_zero());
658 }
659
660 #[test]
661 fn test_neg() {
662 assert_eq!(-(-_1_1v), _1_1v);
663 }
664
665 #[test]
666 fn test_scalar_arithmetic() {
667 assert_eq!(_1_1v * 0.5, _05_05v);
668 assert_eq!(_1_1v / 2.0, _05_05v);
669 assert_eq!(_4_2v % 2.0, _0_0v);
670 assert_eq!(0.5 * _1_1v, _05_05v);
671 }
672
673 #[test]
674 fn test_scalar_arithmetic_ref() {
675 assert_eq!(_1_1v * 0.5, _05_05v);
676 assert_eq!(0.5 * _1_1v, _05_05v);
677 }
678
679 #[test]
680 fn test_dot() {
681 assert_eq!(_1_1v.dot(&_1_1v), 2.0);
682 assert_eq!(_1_1v.dot(&_neg1_1v), 0.0);
683 assert_eq!(_1_1v.dot(&_0_1v), 1.0);
684 }
685
686 #[test]
687 fn test_cross() {
688 assert_eq!(_1_1v.cross(&_1_1v), 0.0);
689 assert_eq!(_1_1v.cross(&_neg1_1v), 2.0);
690 assert_eq!(_1_1v.cross(&_0_1v), 1.0);
691 }
692
693 #[test]
705 fn test_l1_norm() {
706 assert_eq!(_1_1v.l1_norm(), 2.0);
707 assert_eq!(_0_1v.l1_norm(), 1.0);
708 assert_eq!(_neg1_1v.l1_norm(), 2.0);
709 assert_eq!(_05_05v.l1_norm(), 1.0);
710 assert_eq!(_1_0v.l1_norm(), 1.0);
711 assert_eq!(_0_0v.l1_norm(), 0.0);
712 assert_eq!(_4_2v.l1_norm(), 6.0);
713 }
714
715 #[test]
716 fn test_norm_inf() {
717 assert_eq!(_1_1v.norm_inf(), 1.0);
718 assert_eq!(_0_1v.norm_inf(), 1.0);
719 assert_eq!(_neg1_1v.norm_inf(), 1.0);
720 assert_eq!(_05_05v.norm_inf(), 0.5);
721 assert_eq!(_1_0v.norm_inf(), 1.0);
722 assert_eq!(_0_0v.norm_inf(), 0.0);
723 assert_eq!(_4_2v.norm_inf(), 4.0);
724 }
725
726 #[test]
727 fn test_add_assign() {
728 let mut vec_a = _0_1v;
729 vec_a += _1_0v;
730 assert_eq!(vec_a, _1_1v);
731 }
732
733 #[test]
734 fn test_sub_assign() {
735 let mut vec_a = _1_1v;
736 vec_a -= _1_1v;
737 assert_eq!(vec_a, _0_0v);
738 }
739
740 #[test]
741 fn test_mul_assign() {
742 let mut vec_a = _05_05v;
743 vec_a *= 2.0;
744 assert_eq!(vec_a, _1_1v);
745 }
746
747 #[test]
748 fn test_div_assign() {
749 let mut vec_a = _1_1v;
750 vec_a /= 2.0;
751 assert_eq!(vec_a, _05_05v);
752 }
753
754 #[test]
755 fn test_rem() {
756 assert_eq!(_4_2v % 3.0, Vector2::new(1.0, 2.0));
757 }
758
759 #[test]
760 fn test_sub_more() {
761 assert_eq!(_1_1v - _0_1v, _1_0v);
762 assert_eq!(_0_1v - _1_0v, Vector2::new(-1.0, 1.0));
763 }
764
765 #[test]
766 fn test_add_more() {
767 assert_eq!(_1_0v + _0_1v, _1_1v);
768 }
769
770 #[test]
771 fn test_mul_more() {
772 assert_eq!(_1_1v * 2.0, Vector2::new(2.0, 2.0));
773 }
774
775 #[test]
776 fn test_dot_more_cases() {
777 assert_eq!(_0_0v.dot(&_1_1v), 0.0);
778 assert_eq!(_1_1v.dot(&_0_0v), 0.0);
779 assert_eq!(_neg1_1v.dot(&_1_1v), 0.0);
780 }
781
782 #[test]
783 fn test_cross_more_cases() {
784 assert_eq!(_0_0v.cross(&_1_1v), 0.0);
785 assert_eq!(_1_1v.cross(&_0_0v), 0.0);
786 assert_eq!(_neg1_1v.cross(&_1_1v), -2.0);
787 }
788
789 #[test]
790 fn test_l1_norm_more_cases() {
791 assert_eq!(_0_0v.l1_norm(), 0.0);
792 assert_eq!(_neg1_1v.l1_norm(), 2.0);
793 }
794
795 #[test]
796 fn test_norm_inf_more_cases() {
797 assert_eq!(_0_0v.norm_inf(), 0.0);
798 assert_eq!(_neg1_1v.norm_inf(), 1.0);
799 }
800
801 #[test]
802 fn test_scalar_arithmetic_more_cases() {
803 assert_eq!(_0_0v * 2.0, _0_0v);
804 assert_eq!(_1_1v * 0.0, _0_0v);
805 assert_eq!(_1_1v * 1.0, _1_1v);
806 assert_eq!(_1_1v * -1.0, -_1_1v);
807 }
808
809 #[test]
810 fn test_consts_vv() {
811 fn test(
813 vec: Vector2<Vector2<f64, f64>, Vector2<f64, f64>>,
814 w_val: f64,
815 x_val: f64,
816 y_val: f64,
817 z_val: f64,
818 ) {
819 assert_eq!(
820 vec,
821 Vector2::new(Vector2::new(w_val, x_val), Vector2::new(y_val, z_val))
822 );
823 }
824
825 test(_0_0vv, 0.0, 0.0, 0.0, 0.0);
826 test(_0_0_0_0vv, 0.0, 0.0, 0.0, 0.0);
827 test(_1_0_0_0vv, 1.0, 0.0, 0.0, 0.0);
828 test(_1_1_0_0vv, 1.0, 1.0, 0.0, 0.0);
829 test(_0_1_0_0vv, 0.0, 1.0, 0.0, 0.0);
830 test(_neg1_1_0_0vv, -1.0, 1.0, 0.0, 0.0);
831 test(_05_05_0_0vv, 0.5, 0.5, 0.0, 0.0);
832 test(_0_0_1_0vv, 0.0, 0.0, 1.0, 0.0);
833 test(_1_0_1_0vv, 1.0, 0.0, 1.0, 0.0);
834 test(_1_1_1_0vv, 1.0, 1.0, 1.0, 0.0);
835 test(_0_1_1_0vv, 0.0, 1.0, 1.0, 0.0);
836 test(_neg1_1_1_0vv, -1.0, 1.0, 1.0, 0.0);
837 test(_05_05_1_0vv, 0.5, 0.5, 1.0, 0.0);
838 }
839
840 #[test]
850 #[allow(clippy::op_ref, clippy::clone_on_copy)]
851 fn test_mul_ref_scalar() {
852 let v = Vector2::new(3, 4);
853 let s = 2i32;
854
855 assert_eq!(v.clone() * &s, Vector2::new(6, 8));
856 assert_eq!(&v * s, Vector2::new(6, 8));
857 assert_eq!(&v * &s, Vector2::new(6, 8));
858 }
859
860 #[test]
861 #[allow(clippy::op_ref, clippy::clone_on_copy)]
862 fn test_scalar_mul_vec_ref() {
863 let v = Vector2::new(3, 4);
864 let s = 2i32;
865
866 assert_eq!(s * &v, Vector2::new(6, 8));
867 assert_eq!(&s * v.clone(), Vector2::new(6, 8));
868 assert_eq!(&s * &v, Vector2::new(6, 8));
869 }
870}
871
872#[test]
873fn test_neg_ref() {
874 let v = &Vector2::new(1, 2);
875 let neg_v = -v;
876 assert_eq!(neg_v, Vector2::new(-1, -2));
877}
878
879#[test]
880fn test_ref_add_assign_ref() {
881 let mut v1 = Vector2::new(1.0, 2.0);
882 let v2 = &Vector2::new(3.0, 4.0);
883 v1 += v2;
884 assert_eq!(v1, Vector2::new(4.0, 6.0));
885}
886
887#[test]
888fn test_ref_sub_assign_ref() {
889 let mut v1 = Vector2::new(5.0, 7.0);
890 let v2 = &Vector2::new(2.0, 3.0);
891 v1 -= v2;
892 assert_eq!(v1, Vector2::new(3.0, 4.0));
893}
894
895#[test]
896fn test_ref_mul_assign_ref() {
897 let mut v = Vector2::new(2.0, 3.0);
898 let scalar = &2.0;
899 v *= scalar;
900 assert_eq!(v, Vector2::new(4.0, 6.0));
901}
902
903#[test]
904fn test_ref_div_assign_ref() {
905 let mut v = Vector2::new(6.0, 8.0);
906 let scalar = &2.0;
907 v /= scalar;
908 assert_eq!(v, Vector2::new(3.0, 4.0));
909}
910
911#[test]
912fn test_mul_integer_types() {
913 let v = Vector2::new(2i32, 3i32);
914 assert_eq!(v * 2i32, Vector2::new(4, 6));
915
916 let v2 = Vector2::new(2u8, 3u8);
917 assert_eq!(v2 * 2u8, Vector2::new(4, 6));
918}
919
920#[test]
921fn test_neg_edge_cases() {
922 let v_zero = Vector2::new(0.0, 0.0);
923 assert_eq!(-v_zero, Vector2::new(-0.0, -0.0));
924
925 let v_neg = Vector2::new(-1.0, -2.0);
926 assert_eq!(-v_neg, Vector2::new(1.0, 2.0));
927}
928
929#[test]
930fn test_scalar_mul_i32_ref() {
931 let v = Vector2::new(2i32, 3i32);
932 let result = v * 2i32;
933 assert_eq!(result, Vector2::new(4, 6));
934}