1use core::ops::{Add, Div, Mul, Neg, Rem, Sub};
3use num_traits::{Num, Zero};
4
5use super::Vector2;
7
8#[cfg_attr(feature = "doc-images", doc = svgbobdoc::transform!(
19))]
27#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug, Default)]
28pub struct Matrix2<T> {
30 pub x_: Vector2<T>,
32 pub y_: Vector2<T>,
34}
35
36impl<T> Matrix2<T> {
37 #[inline]
61 pub const fn new(x_: Vector2<T>, y_: Vector2<T>) -> Self {
62 Matrix2 { x_, y_ }
63 }
64}
65
66impl<T: Clone + Num> Matrix2<T> {
67 #[inline]
89 pub fn det(&self) -> T {
90 self.x_.cross(&self.y_)
91 }
92
93 #[inline]
121 pub fn mdot(&self, v: &Vector2<T>) -> Vector2<T> {
122 Vector2::<T>::new(self.x_.dot(v), self.y_.dot(v))
123 }
124
125 #[inline]
149 pub fn scale(&self, alpha: T) -> Self {
150 Self::new(self.x_.clone() * alpha.clone(), self.y_.clone() * alpha)
151 }
152
153 #[inline]
179 pub fn unscale(&self, alpha: T) -> Self {
180 Self::new(self.x_.clone() / alpha.clone(), self.y_.clone() / alpha)
181 }
182}
183
184macro_rules! forward_xf_xf_binop {
185 (impl $imp:ident, $method:ident) => {
186 impl<'a, 'b, T: Clone + Num> $imp<&'b Matrix2<T>> for &'a Matrix2<T> {
187 type Output = Matrix2<T>;
188
189 #[inline]
190 fn $method(self, other: &Matrix2<T>) -> Self::Output {
191 self.clone().$method(other.clone())
192 }
193 }
194 };
195}
196
197macro_rules! forward_xf_val_binop {
198 (impl $imp:ident, $method:ident) => {
199 impl<'a, T: Clone + Num> $imp<Matrix2<T>> for &'a Matrix2<T> {
200 type Output = Matrix2<T>;
201
202 #[inline]
203 fn $method(self, other: Matrix2<T>) -> Self::Output {
204 self.clone().$method(other)
205 }
206 }
207 };
208}
209
210macro_rules! forward_val_xf_binop {
211 (impl $imp:ident, $method:ident) => {
212 impl<'a, T: Clone + Num> $imp<&'a Matrix2<T>> for Matrix2<T> {
213 type Output = Matrix2<T>;
214
215 #[inline]
216 fn $method(self, other: &Matrix2<T>) -> Self::Output {
217 self.$method(other.clone())
218 }
219 }
220 };
221}
222
223macro_rules! forward_all_binop {
224 (impl $imp:ident, $method:ident) => {
225 forward_xf_xf_binop!(impl $imp, $method);
226 forward_xf_val_binop!(impl $imp, $method);
227 forward_val_xf_binop!(impl $imp, $method);
228 };
229}
230
231forward_all_binop!(impl Add, add);
233
234impl<T: Clone + Num> Add<Matrix2<T>> for Matrix2<T> {
238 type Output = Self;
239
240 #[inline]
241 fn add(self, other: Self) -> Self::Output {
242 Self::Output::new(self.x_ + other.x_, self.y_ + other.y_)
243 }
244}
245
246forward_all_binop!(impl Sub, sub);
247
248impl<T: Clone + Num> Sub<Matrix2<T>> for Matrix2<T> {
252 type Output = Self;
253
254 #[inline]
255 fn sub(self, other: Self) -> Self::Output {
256 Self::Output::new(self.x_ - other.x_, self.y_ - other.y_)
257 }
258}
259
260mod opassign {
263 use core::ops::{AddAssign, DivAssign, MulAssign, SubAssign};
264
265 use num_traits::NumAssign;
266
267 use crate::Matrix2;
268
269 impl<T: Clone + NumAssign> AddAssign for Matrix2<T> {
270 fn add_assign(&mut self, other: Self) {
271 self.x_ += other.x_;
272 self.y_ += other.y_;
273 }
274 }
275
276 impl<T: Clone + NumAssign> SubAssign for Matrix2<T> {
277 fn sub_assign(&mut self, other: Self) {
278 self.x_ -= other.x_;
279 self.y_ -= other.y_;
280 }
281 }
282
283 impl<T: Clone + NumAssign> MulAssign<T> for Matrix2<T> {
284 fn mul_assign(&mut self, other: T) {
285 self.x_ *= other.clone();
286 self.y_ *= other;
287 }
288 }
289
290 impl<T: Clone + NumAssign> DivAssign<T> for Matrix2<T> {
291 fn div_assign(&mut self, other: T) {
292 self.x_ /= other.clone();
293 self.y_ /= other;
294 }
295 }
296
297 macro_rules! forward_op_assign1 {
298 (impl $imp:ident, $method:ident) => {
299 impl<'a, T: Clone + NumAssign> $imp<&'a Matrix2<T>> for Matrix2<T> {
300 #[inline]
301 fn $method(&mut self, other: &Self) {
302 self.$method(other.clone())
303 }
304 }
305 };
306 }
307
308 macro_rules! forward_op_assign2 {
309 (impl $imp:ident, $method:ident) => {
310 impl<'a, T: Clone + NumAssign> $imp<&'a T> for Matrix2<T> {
311 #[inline]
312 fn $method(&mut self, other: &T) {
313 self.$method(other.clone())
314 }
315 }
316 };
317 }
318
319 forward_op_assign1!(impl AddAssign, add_assign);
320 forward_op_assign1!(impl SubAssign, sub_assign);
321 forward_op_assign2!(impl MulAssign, mul_assign);
322 forward_op_assign2!(impl DivAssign, div_assign);
323}
324
325impl<T: Clone + Num + Neg<Output = T>> Neg for Matrix2<T> {
329 type Output = Self;
330
331 #[inline]
332 fn neg(self) -> Self::Output {
333 Self::Output::new(-self.x_, -self.y_)
334 }
335}
336
337impl<T: Clone + Num + Neg<Output = T>> Neg for &Matrix2<T> {
341 type Output = Matrix2<T>;
342
343 #[inline]
344 fn neg(self) -> Self::Output {
345 -self.clone()
346 }
347}
348
349macro_rules! scalar_arithmetic {
350 (@forward $imp:ident::$method:ident for $($scalar:ident),*) => (
351 impl<'a, T: Clone + Num> $imp<&'a T> for Matrix2<T> {
352 type Output = Matrix2<T>;
353
354 #[inline]
355 fn $method(self, other: &T) -> Self::Output {
356 self.$method(other.clone())
357 }
358 }
359 impl<'a, T: Clone + Num> $imp<T> for &'a Matrix2<T> {
360 type Output = Matrix2<T>;
361
362 #[inline]
363 fn $method(self, other: T) -> Self::Output {
364 self.clone().$method(other)
365 }
366 }
367 impl<'a, 'b, T: Clone + Num> $imp<&'a T> for &'b Matrix2<T> {
368 type Output = Matrix2<T>;
369
370 #[inline]
371 fn $method(self, other: &T) -> Self::Output {
372 self.clone().$method(other.clone())
373 }
374 }
375 $(
376 impl<'a> $imp<&'a Matrix2<$scalar>> for $scalar {
377 type Output = Matrix2<$scalar>;
378
379 #[inline]
380 fn $method(self, other: &Matrix2<$scalar>) -> Matrix2<$scalar> {
381 self.$method(other.clone())
382 }
383 }
384 impl<'a> $imp<Matrix2<$scalar>> for &'a $scalar {
385 type Output = Matrix2<$scalar>;
386
387 #[inline]
388 fn $method(self, other: Matrix2<$scalar>) -> Matrix2<$scalar> {
389 self.clone().$method(other)
390 }
391 }
392 impl<'a, 'b> $imp<&'a Matrix2<$scalar>> for &'b $scalar {
393 type Output = Matrix2<$scalar>;
394
395 #[inline]
396 fn $method(self, other: &Matrix2<$scalar>) -> Matrix2<$scalar> {
397 self.clone().$method(other.clone())
398 }
399 }
400 )*
401 );
402 ($($scalar:ident),*) => (
403 scalar_arithmetic!(@forward Mul::mul for $($scalar),*);
404 $(
408 impl Mul<Matrix2<$scalar>> for $scalar {
409 type Output = Matrix2<$scalar>;
410
411 #[inline]
412 fn mul(self, other: Matrix2<$scalar>) -> Self::Output {
413 Self::Output::new(self * other.x_, self * other.y_)
414 }
415 }
416
417 )*
418 );
419}
420
421impl<T: Clone + Num> Mul<T> for Matrix2<T> {
425 type Output = Matrix2<T>;
426
427 #[inline]
428 fn mul(self, other: T) -> Self::Output {
429 Self::Output::new(self.x_ * other.clone(), self.y_ * other)
430 }
431}
432
433impl<T: Clone + Num> Div<T> for Matrix2<T> {
437 type Output = Self;
438
439 #[inline]
440 fn div(self, other: T) -> Self::Output {
441 Self::Output::new(self.x_ / other.clone(), self.y_ / other)
442 }
443}
444
445impl<T: Clone + Num> Rem<T> for Matrix2<T> {
449 type Output = Matrix2<T>;
450
451 #[inline]
452 fn rem(self, other: T) -> Self::Output {
453 Self::Output::new(self.x_ % other.clone(), self.y_ % other)
454 }
455}
456
457scalar_arithmetic!(usize, u8, u16, u32, u64, u128, isize, i8, i16, i32, i64, i128, f32, f64);
458
459impl<T: Clone + Num> Zero for Matrix2<T> {
461 #[inline]
465 fn zero() -> Self {
466 Self::new(Zero::zero(), Zero::zero())
467 }
468
469 #[inline]
473 fn is_zero(&self) -> bool {
474 self.x_.is_zero() && self.y_.is_zero()
475 }
476
477 #[inline]
478 fn set_zero(&mut self) {
479 self.x_.set_zero();
480 self.y_.set_zero();
481 }
482}
483
484#[cfg(test)]
494mod test {
495 #![allow(non_upper_case_globals)]
496
497 use super::{Matrix2, Vector2};
499 use core::f64;
500 use num_traits::Zero;
501
502 pub const _0_0v: Vector2<f64> = Vector2 { x_: 0.0, y_: 0.0 };
503 pub const _1_0v: Vector2<f64> = Vector2 { x_: 1.0, y_: 0.0 };
504 pub const _1_1v: Vector2<f64> = Vector2 { x_: 1.0, y_: 1.0 };
505 pub const _0_1v: Vector2<f64> = Vector2 { x_: 0.0, y_: 1.0 };
506 pub const _neg1_1v: Vector2<f64> = Vector2 { x_: -1.0, y_: 1.0 };
507 pub const _05_05v: Vector2<f64> = Vector2 { x_: 0.5, y_: 0.5 };
508 pub const _4_2v: Vector2<f64> = Vector2 { x_: 4.0, y_: 2.0 };
510
511 pub const _0_0m: Matrix2<f64> = Matrix2 {
512 x_: _0_0v,
513 y_: _0_0v,
514 };
515 pub const _1_0m: Matrix2<f64> = Matrix2 {
516 x_: _1_0v,
517 y_: _0_0v,
518 };
519 pub const _1_1m: Matrix2<f64> = Matrix2 {
520 x_: _1_1v,
521 y_: _1_1v,
522 };
523 pub const _0_1m: Matrix2<f64> = Matrix2 {
524 x_: _0_0v,
525 y_: _1_0v,
526 };
527 pub const _neg1_1m: Matrix2<f64> = Matrix2 {
528 x_: _neg1_1v,
529 y_: _1_0v,
530 };
531 pub const _05_05m: Matrix2<f64> = Matrix2 {
532 x_: _05_05v,
533 y_: _05_05v,
534 };
535 pub const all_consts: [Matrix2<f64>; 5] = [_0_0m, _1_0m, _1_1m, _neg1_1m, _05_05m];
536 pub const _4_2m: Matrix2<f64> = Matrix2 {
537 x_: _4_2v,
538 y_: _4_2v,
539 };
540
541 #[test]
542 fn test_consts() {
543 assert_eq!(_0_0m, Zero::zero());
554 }
555
556 #[test]
557 fn test_scale_unscale() {
558 assert_eq!(_05_05m.scale(2.0), _1_1m);
559 assert_eq!(_1_1m.unscale(2.0), _05_05m);
560 for &c in all_consts.iter() {
561 assert_eq!(c.scale(2.0).unscale(2.0), c);
562 }
563 }
564
565 #[test]
579 fn test_new() {
580 let x = Vector2::new(1, 2);
581 let y = Vector2::new(3, 4);
582 let m = Matrix2::new(x, y);
583 assert_eq!(m.x_, x);
584 assert_eq!(m.y_, y);
585 }
586
587 #[test]
588 fn test_det() {
589 let m = Matrix2::new(Vector2::new(3, 4), Vector2::new(5, 6));
590 assert_eq!(m.det(), 3 * 6 - 4 * 5);
591
592 let m2 = Matrix2::new(Vector2::new(1.0, 2.0), Vector2::new(3.0, 4.0));
593 assert_eq!(m2.det(), -2.0);
594 }
595
596 #[test]
597 fn test_mdot() {
598 let m = Matrix2::new(Vector2::new(3, 4), Vector2::new(5, 6));
599 let v = Vector2::new(1, 1);
600 assert_eq!(m.mdot(&v), Vector2::new(7, 11));
601
602 let m2 = Matrix2::new(Vector2::new(1.0, 2.0), Vector2::new(3.0, 4.0));
603 let v2 = Vector2::new(2.0, 3.0);
604 assert_eq!(m2.mdot(&v2), Vector2::new(8.0, 18.0));
605 }
606
607 #[test]
608 fn test_scale() {
609 let m = Matrix2::new(Vector2::new(3, 4), Vector2::new(5, 6));
610 assert_eq!(
611 m.scale(2),
612 Matrix2::new(Vector2::new(6, 8), Vector2::new(10, 12))
613 );
614
615 let m2 = Matrix2::new(Vector2::new(1.5, 2.5), Vector2::new(3.5, 4.5));
616 assert_eq!(
617 m2.scale(2.0),
618 Matrix2::new(Vector2::new(3.0, 5.0), Vector2::new(7.0, 9.0))
619 );
620 }
621
622 #[test]
623 fn test_unscale() {
624 let m = Matrix2::new(Vector2::new(30, 40), Vector2::new(50, 60));
625 assert_eq!(
626 m.unscale(10),
627 Matrix2::new(Vector2::new(3, 4), Vector2::new(5, 6))
628 );
629
630 let m2 = Matrix2::new(Vector2::new(3.0, 5.0), Vector2::new(7.0, 9.0));
631 assert_eq!(
632 m2.unscale(2.0),
633 Matrix2::new(Vector2::new(1.5, 2.5), Vector2::new(3.5, 4.5))
634 );
635 }
636
637 #[test]
638 fn test_add() {
639 let m1 = Matrix2::new(Vector2::new(1, 2), Vector2::new(3, 4));
640 let m2 = Matrix2::new(Vector2::new(5, 6), Vector2::new(7, 8));
641 assert_eq!(
642 m1 + m2,
643 Matrix2::new(Vector2::new(6, 8), Vector2::new(10, 12))
644 );
645
646 let m3 = m1 + m2;
647 assert_eq!(m3, Matrix2::new(Vector2::new(6, 8), Vector2::new(10, 12)));
648
649 let m4 = m1 + m2;
650 assert_eq!(m4, Matrix2::new(Vector2::new(6, 8), Vector2::new(10, 12)));
651 }
652
653 #[test]
654 fn test_sub() {
655 let m1 = Matrix2::new(Vector2::new(5, 6), Vector2::new(7, 8));
656 let m2 = Matrix2::new(Vector2::new(1, 2), Vector2::new(3, 4));
657 assert_eq!(
658 m1 - m2,
659 Matrix2::new(Vector2::new(4, 4), Vector2::new(4, 4))
660 );
661
662 let m3 = m1 - m2;
663 assert_eq!(m3, Matrix2::new(Vector2::new(4, 4), Vector2::new(4, 4)));
664 }
665
666 #[test]
667 fn test_neg() {
668 let m = Matrix2::new(Vector2::new(1, -2), Vector2::new(-3, 4));
669 assert_eq!(-m, Matrix2::new(Vector2::new(-1, 2), Vector2::new(3, -4)));
670 assert_eq!(-&m, Matrix2::new(Vector2::new(-1, 2), Vector2::new(3, -4)));
671 }
672
673 #[test]
674 fn test_scalar_mul() {
675 let m = Matrix2::new(Vector2::new(2, 3), Vector2::new(4, 5));
676 assert_eq!(
677 m * 4,
678 Matrix2::new(Vector2::new(8, 12), Vector2::new(16, 20))
679 );
680 assert_eq!(
681 &m * 4,
682 Matrix2::new(Vector2::new(8, 12), Vector2::new(16, 20))
683 );
684 assert_eq!(
685 4 * m,
686 Matrix2::new(Vector2::new(8, 12), Vector2::new(16, 20))
687 );
688 assert_eq!(
689 4 * &m,
690 Matrix2::new(Vector2::new(8, 12), Vector2::new(16, 20))
691 );
692 }
693
694 #[test]
695 fn test_scalar_div() {
696 let m = Matrix2::new(Vector2::new(10, 20), Vector2::new(30, 40));
697 assert_eq!(m / 5, Matrix2::new(Vector2::new(2, 4), Vector2::new(6, 8)));
698 }
699
700 #[test]
701 fn test_scalar_rem() {
702 let m = Matrix2::new(Vector2::new(10, 21), Vector2::new(32, 43));
703 assert_eq!(m % 3, Matrix2::new(Vector2::new(1, 0), Vector2::new(2, 1)));
704 }
705
706 #[test]
707 fn test_zero() {
708 let zero = Matrix2::<i32>::zero();
709 assert_eq!(zero, Matrix2::new(Vector2::zero(), Vector2::zero()));
710 assert!(zero.is_zero());
711
712 let mut m = Matrix2::new(Vector2::new(1, 2), Vector2::new(3, 4));
713 assert!(!m.is_zero());
714 m.set_zero();
715 assert!(m.is_zero());
716 }
717
718 #[test]
719 fn test_add_assign() {
720 let mut m1 = Matrix2::new(Vector2::new(1, 2), Vector2::new(3, 4));
721 let m2 = Matrix2::new(Vector2::new(5, 6), Vector2::new(7, 8));
722 m1 += m2;
723 assert_eq!(m1, Matrix2::new(Vector2::new(6, 8), Vector2::new(10, 12)));
724
725 let mut m3 = Matrix2::new(Vector2::new(1, 2), Vector2::new(3, 4));
726 m3 += &m2;
727 assert_eq!(m3, Matrix2::new(Vector2::new(6, 8), Vector2::new(10, 12)));
728 }
729
730 #[test]
731 fn test_sub_assign() {
732 let mut m1 = Matrix2::new(Vector2::new(5, 6), Vector2::new(7, 8));
733 let m2 = Matrix2::new(Vector2::new(1, 2), Vector2::new(3, 4));
734 m1 -= m2;
735 assert_eq!(m1, Matrix2::new(Vector2::new(4, 4), Vector2::new(4, 4)));
736
737 let mut m3 = Matrix2::new(Vector2::new(5, 6), Vector2::new(7, 8));
738 m3 -= &m2;
739 assert_eq!(m3, Matrix2::new(Vector2::new(4, 4), Vector2::new(4, 4)));
740 }
741
742 #[test]
743 fn test_mul_assign() {
744 let mut m = Matrix2::new(Vector2::new(1, 2), Vector2::new(3, 4));
745 m *= 3;
746 assert_eq!(m, Matrix2::new(Vector2::new(3, 6), Vector2::new(9, 12)));
747
748 let mut m2 = Matrix2::new(Vector2::new(1, 2), Vector2::new(3, 4));
749 let scalar = 3;
750 m2 *= &scalar;
751 assert_eq!(m2, Matrix2::new(Vector2::new(3, 6), Vector2::new(9, 12)));
752 }
753
754 #[test]
755 fn test_div_assign() {
756 let mut m = Matrix2::new(Vector2::new(6, 9), Vector2::new(12, 15));
757 m /= 3;
758 assert_eq!(m, Matrix2::new(Vector2::new(2, 3), Vector2::new(4, 5)));
759
760 let mut m2 = Matrix2::new(Vector2::new(6, 9), Vector2::new(12, 15));
761 let scalar = 3;
762 m2 /= &scalar;
763 assert_eq!(m2, Matrix2::new(Vector2::new(2, 3), Vector2::new(4, 5)));
764 }
765
766 #[test]
767 fn test_float_operations() {
768 let m = Matrix2::new(Vector2::new(1.5, 2.5), Vector2::new(3.5, 4.5));
769 assert_eq!(
770 m.scale(2.0),
771 Matrix2::new(Vector2::new(3.0, 5.0), Vector2::new(7.0, 9.0))
772 );
773 assert_eq!(
774 m.unscale(0.5),
775 Matrix2::new(Vector2::new(3.0, 5.0), Vector2::new(7.0, 9.0))
776 );
777 assert_eq!(m.det(), 1.5 * 4.5 - 2.5 * 3.5);
778 }
779
780 #[test]
781 fn test_clone_and_eq() {
782 let m1 = Matrix2::new(Vector2::new(1, 2), Vector2::new(3, 4));
783 let m2 = m1;
784 assert_eq!(m1, m2);
785
786 let m3 = Matrix2::new(Vector2::new(2, 1), Vector2::new(4, 3));
787 assert_ne!(m1, m3);
788 }
789
790 #[test]
791 fn test_debug() {
792 let m = Matrix2::new(Vector2::new(1, 2), Vector2::new(3, 4));
793 assert_eq!(
794 format!("{:?}", m),
795 "Matrix2 { x_: Vector2 { x_: 1, y_: 2 }, y_: Vector2 { x_: 3, y_: 4 } }"
796 );
797 }
798
799 #[test]
800 fn test_forward_xf_val_binop() {
801 let m1 = Matrix2::new(Vector2::new(1, 2), Vector2::new(3, 4));
802 let m2 = Matrix2::new(Vector2::new(5, 6), Vector2::new(7, 8));
803 let result: Matrix2<i32> = m1 + m2;
804 assert_eq!(
805 result,
806 Matrix2::new(Vector2::new(6, 8), Vector2::new(10, 12))
807 );
808 }
809
810 #[test]
811 fn test_forward_val_xf_binop() {
812 let m1 = Matrix2::new(Vector2::new(1, 2), Vector2::new(3, 4));
813 let m2 = Matrix2::new(Vector2::new(5, 6), Vector2::new(7, 8));
814 let result: Matrix2<i32> = m1 + m2;
815 assert_eq!(
816 result,
817 Matrix2::new(Vector2::new(6, 8), Vector2::new(10, 12))
818 );
819 }
820
821 #[test]
822 fn test_scalar_arithmetic_forward() {
823 let m = Matrix2::new(Vector2::new(2, 3), Vector2::new(4, 5));
824 let scalar = 3;
825 let result: Matrix2<i32> = m * scalar;
826 assert_eq!(
827 result,
828 Matrix2::new(Vector2::new(6, 9), Vector2::new(12, 15))
829 );
830
831 let result2: Matrix2<i32> = m * scalar;
832 assert_eq!(
833 result2,
834 Matrix2::new(Vector2::new(6, 9), Vector2::new(12, 15))
835 );
836
837 let result3: Matrix2<i32> = 3 * &m;
838 assert_eq!(
839 result3,
840 Matrix2::new(Vector2::new(6, 9), Vector2::new(12, 15))
841 );
842 }
843
844 #[test]
845 fn test_scalar_left_mul() {
846 let m = Matrix2::new(Vector2::new(2, 3), Vector2::new(4, 5));
847 assert_eq!(
848 3 * m,
849 Matrix2::new(Vector2::new(6, 9), Vector2::new(12, 15))
850 );
851 assert_eq!(
852 3 * &m,
853 Matrix2::new(Vector2::new(6, 9), Vector2::new(12, 15))
854 );
855 }
856
857 #[test]
858 fn test_scalar_mul_by_ref_matrix() {
859 let m = Matrix2::new(Vector2::new(1, 2), Vector2::new(3, 4));
860 assert_eq!(
861 5 * &m,
862 Matrix2::new(Vector2::new(5, 10), Vector2::new(15, 20))
863 );
864 }
865}