1use core::ops::{Add, Div, Mul, Neg, Rem, Sub};
3use num_traits::{Num, Zero};
4
5use super::Vector2;
7
8#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug, Default)]
19pub struct Matrix2<T> {
21 pub x_: Vector2<T>,
23 pub y_: Vector2<T>,
25}
26
27impl<T> Matrix2<T> {
28 #[inline]
52 pub const fn new(x_: Vector2<T>, y_: Vector2<T>) -> Self {
53 Matrix2 { x_, y_ }
54 }
55}
56
57impl<T: Clone + Num> Matrix2<T> {
58 #[inline]
80 pub fn det(&self) -> T {
81 self.x_.cross(&self.y_)
82 }
83
84 #[inline]
112 pub fn mdot(&self, v: &Vector2<T>) -> Vector2<T> {
113 Vector2::<T>::new(self.x_.dot(v), self.y_.dot(v))
114 }
115
116 #[inline]
138 pub fn scale(&self, alpha: T) -> Self {
139 Self::new(self.x_.clone() * alpha.clone(), self.y_.clone() * alpha)
140 }
141
142 #[inline]
166 pub fn unscale(&self, alpha: T) -> Self {
167 Self::new(self.x_.clone() / alpha.clone(), self.y_.clone() / alpha)
168 }
169}
170
171macro_rules! forward_xf_xf_binop {
172 (impl $imp:ident, $method:ident) => {
173 impl<'a, 'b, T: Clone + Num> $imp<&'b Matrix2<T>> for &'a Matrix2<T> {
174 type Output = Matrix2<T>;
175
176 #[inline]
177 fn $method(self, other: &Matrix2<T>) -> Self::Output {
178 self.clone().$method(other.clone())
179 }
180 }
181 };
182}
183
184macro_rules! forward_xf_val_binop {
185 (impl $imp:ident, $method:ident) => {
186 impl<'a, T: Clone + Num> $imp<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)
192 }
193 }
194 };
195}
196
197macro_rules! forward_val_xf_binop {
198 (impl $imp:ident, $method:ident) => {
199 impl<'a, T: Clone + Num> $imp<&'a Matrix2<T>> for Matrix2<T> {
200 type Output = Matrix2<T>;
201
202 #[inline]
203 fn $method(self, other: &Matrix2<T>) -> Self::Output {
204 self.$method(other.clone())
205 }
206 }
207 };
208}
209
210macro_rules! forward_all_binop {
211 (impl $imp:ident, $method:ident) => {
212 forward_xf_xf_binop!(impl $imp, $method);
213 forward_xf_val_binop!(impl $imp, $method);
214 forward_val_xf_binop!(impl $imp, $method);
215 };
216}
217
218forward_all_binop!(impl Add, add);
220
221impl<T: Clone + Num> Add<Matrix2<T>> for Matrix2<T> {
223 type Output = Self;
224
225 #[inline]
226 fn add(self, other: Self) -> Self::Output {
227 Self::Output::new(self.x_ + other.x_, self.y_ + other.y_)
228 }
229}
230
231forward_all_binop!(impl Sub, sub);
232
233impl<T: Clone + Num> Sub<Matrix2<T>> for Matrix2<T> {
235 type Output = Self;
236
237 #[inline]
238 fn sub(self, other: Self) -> Self::Output {
239 Self::Output::new(self.x_ - other.x_, self.y_ - other.y_)
240 }
241}
242
243mod opassign {
246 use core::ops::{AddAssign, DivAssign, MulAssign, SubAssign};
247
248 use num_traits::NumAssign;
249
250 use crate::Matrix2;
251
252 impl<T: Clone + NumAssign> AddAssign for Matrix2<T> {
253 fn add_assign(&mut self, other: Self) {
254 self.x_ += other.x_;
255 self.y_ += other.y_;
256 }
257 }
258
259 impl<T: Clone + NumAssign> SubAssign for Matrix2<T> {
260 fn sub_assign(&mut self, other: Self) {
261 self.x_ -= other.x_;
262 self.y_ -= other.y_;
263 }
264 }
265
266 impl<T: Clone + NumAssign> MulAssign<T> for Matrix2<T> {
267 fn mul_assign(&mut self, other: T) {
268 self.x_ *= other.clone();
269 self.y_ *= other;
270 }
271 }
272
273 impl<T: Clone + NumAssign> DivAssign<T> for Matrix2<T> {
274 fn div_assign(&mut self, other: T) {
275 self.x_ /= other.clone();
276 self.y_ /= other;
277 }
278 }
279
280 macro_rules! forward_op_assign1 {
281 (impl $imp:ident, $method:ident) => {
282 impl<'a, T: Clone + NumAssign> $imp<&'a Matrix2<T>> for Matrix2<T> {
283 #[inline]
284 fn $method(&mut self, other: &Self) {
285 self.$method(other.clone())
286 }
287 }
288 };
289 }
290
291 macro_rules! forward_op_assign2 {
292 (impl $imp:ident, $method:ident) => {
293 impl<'a, T: Clone + NumAssign> $imp<&'a T> for Matrix2<T> {
294 #[inline]
295 fn $method(&mut self, other: &T) {
296 self.$method(other.clone())
297 }
298 }
299 };
300 }
301
302 forward_op_assign1!(impl AddAssign, add_assign);
303 forward_op_assign1!(impl SubAssign, sub_assign);
304 forward_op_assign2!(impl MulAssign, mul_assign);
305 forward_op_assign2!(impl DivAssign, div_assign);
306}
307
308impl<T: Clone + Num + Neg<Output = T>> Neg for Matrix2<T> {
309 type Output = Self;
310
311 #[inline]
312 fn neg(self) -> Self::Output {
313 Self::Output::new(-self.x_, -self.y_)
314 }
315}
316
317impl<T: Clone + Num + Neg<Output = T>> Neg for &Matrix2<T> {
318 type Output = Matrix2<T>;
319
320 #[inline]
321 fn neg(self) -> Self::Output {
322 -self.clone()
323 }
324}
325
326macro_rules! scalar_arithmetic {
327 (@forward $imp:ident::$method:ident for $($scalar:ident),*) => (
328 impl<'a, T: Clone + Num> $imp<&'a T> for Matrix2<T> {
329 type Output = Matrix2<T>;
330
331 #[inline]
332 fn $method(self, other: &T) -> Self::Output {
333 self.$method(other.clone())
334 }
335 }
336 impl<'a, T: Clone + Num> $imp<T> for &'a Matrix2<T> {
337 type Output = Matrix2<T>;
338
339 #[inline]
340 fn $method(self, other: T) -> Self::Output {
341 self.clone().$method(other)
342 }
343 }
344 impl<'a, 'b, T: Clone + Num> $imp<&'a T> for &'b Matrix2<T> {
345 type Output = Matrix2<T>;
346
347 #[inline]
348 fn $method(self, other: &T) -> Self::Output {
349 self.clone().$method(other.clone())
350 }
351 }
352 $(
353 impl<'a> $imp<&'a Matrix2<$scalar>> for $scalar {
354 type Output = Matrix2<$scalar>;
355
356 #[inline]
357 fn $method(self, other: &Matrix2<$scalar>) -> Matrix2<$scalar> {
358 self.$method(other.clone())
359 }
360 }
361 impl<'a> $imp<Matrix2<$scalar>> for &'a $scalar {
362 type Output = Matrix2<$scalar>;
363
364 #[inline]
365 fn $method(self, other: Matrix2<$scalar>) -> Matrix2<$scalar> {
366 self.clone().$method(other)
367 }
368 }
369 impl<'a, 'b> $imp<&'a Matrix2<$scalar>> for &'b $scalar {
370 type Output = Matrix2<$scalar>;
371
372 #[inline]
373 fn $method(self, other: &Matrix2<$scalar>) -> Matrix2<$scalar> {
374 self.clone().$method(other.clone())
375 }
376 }
377 )*
378 );
379 ($($scalar:ident),*) => (
380 scalar_arithmetic!(@forward Mul::mul for $($scalar),*);
381 $(
385 impl Mul<Matrix2<$scalar>> for $scalar {
386 type Output = Matrix2<$scalar>;
387
388 #[inline]
389 fn mul(self, other: Matrix2<$scalar>) -> Self::Output {
390 Self::Output::new(self * other.x_, self * other.y_)
391 }
392 }
393
394 )*
395 );
396}
397
398impl<T: Clone + Num> Mul<T> for Matrix2<T> {
399 type Output = Matrix2<T>;
400
401 #[inline]
402 fn mul(self, other: T) -> Self::Output {
403 Self::Output::new(self.x_ * other.clone(), self.y_ * other)
404 }
405}
406
407impl<T: Clone + Num> Div<T> for Matrix2<T> {
408 type Output = Self;
409
410 #[inline]
411 fn div(self, other: T) -> Self::Output {
412 Self::Output::new(self.x_ / other.clone(), self.y_ / other)
413 }
414}
415
416impl<T: Clone + Num> Rem<T> for Matrix2<T> {
417 type Output = Matrix2<T>;
418
419 #[inline]
420 fn rem(self, other: T) -> Self::Output {
421 Self::Output::new(self.x_ % other.clone(), self.y_ % other)
422 }
423}
424
425scalar_arithmetic!(usize, u8, u16, u32, u64, u128, isize, i8, i16, i32, i64, i128, f32, f64);
426
427impl<T: Clone + Num> Zero for Matrix2<T> {
429 #[inline]
430 fn zero() -> Self {
431 Self::new(Zero::zero(), Zero::zero())
432 }
433
434 #[inline]
435 fn is_zero(&self) -> bool {
436 self.x_.is_zero() && self.y_.is_zero()
437 }
438
439 #[inline]
440 fn set_zero(&mut self) {
441 self.x_.set_zero();
442 self.y_.set_zero();
443 }
444}
445
446#[cfg(test)]
456mod test {
457 #![allow(non_upper_case_globals)]
458
459 use super::{Matrix2, Vector2};
461 use core::f64;
462 use num_traits::Zero;
463
464 pub const _0_0v: Vector2<f64> = Vector2 { x_: 0.0, y_: 0.0 };
465 pub const _1_0v: Vector2<f64> = Vector2 { x_: 1.0, y_: 0.0 };
466 pub const _1_1v: Vector2<f64> = Vector2 { x_: 1.0, y_: 1.0 };
467 pub const _0_1v: Vector2<f64> = Vector2 { x_: 0.0, y_: 1.0 };
468 pub const _neg1_1v: Vector2<f64> = Vector2 { x_: -1.0, y_: 1.0 };
469 pub const _05_05v: Vector2<f64> = Vector2 { x_: 0.5, y_: 0.5 };
470 pub const _4_2v: Vector2<f64> = Vector2 { x_: 4.0, y_: 2.0 };
472
473 pub const _0_0m: Matrix2<f64> = Matrix2 {
474 x_: _0_0v,
475 y_: _0_0v,
476 };
477 pub const _1_0m: Matrix2<f64> = Matrix2 {
478 x_: _1_0v,
479 y_: _0_0v,
480 };
481 pub const _1_1m: Matrix2<f64> = Matrix2 {
482 x_: _1_1v,
483 y_: _1_1v,
484 };
485 pub const _0_1m: Matrix2<f64> = Matrix2 {
486 x_: _0_0v,
487 y_: _1_0v,
488 };
489 pub const _neg1_1m: Matrix2<f64> = Matrix2 {
490 x_: _neg1_1v,
491 y_: _1_0v,
492 };
493 pub const _05_05m: Matrix2<f64> = Matrix2 {
494 x_: _05_05v,
495 y_: _05_05v,
496 };
497 pub const all_consts: [Matrix2<f64>; 5] = [_0_0m, _1_0m, _1_1m, _neg1_1m, _05_05m];
498 pub const _4_2m: Matrix2<f64> = Matrix2 {
499 x_: _4_2v,
500 y_: _4_2v,
501 };
502
503 #[test]
504 fn test_consts() {
505 assert_eq!(_0_0m, Zero::zero());
516 }
517
518 #[test]
519 fn test_scale_unscale() {
520 assert_eq!(_05_05m.scale(2.0), _1_1m);
521 assert_eq!(_1_1m.unscale(2.0), _05_05m);
522 for &c in all_consts.iter() {
523 assert_eq!(c.scale(2.0).unscale(2.0), c);
524 }
525 }
526
527 #[test]
541 fn test_new() {
542 let x = Vector2::new(1, 2);
543 let y = Vector2::new(3, 4);
544 let m = Matrix2::new(x, y);
545 assert_eq!(m.x_, x);
546 assert_eq!(m.y_, y);
547 }
548
549 #[test]
550 fn test_det() {
551 let m = Matrix2::new(Vector2::new(3, 4), Vector2::new(5, 6));
552 assert_eq!(m.det(), 3 * 6 - 4 * 5);
553
554 let m2 = Matrix2::new(Vector2::new(1.0, 2.0), Vector2::new(3.0, 4.0));
555 assert_eq!(m2.det(), -2.0);
556 }
557
558 #[test]
559 fn test_mdot() {
560 let m = Matrix2::new(Vector2::new(3, 4), Vector2::new(5, 6));
561 let v = Vector2::new(1, 1);
562 assert_eq!(m.mdot(&v), Vector2::new(7, 11));
563
564 let m2 = Matrix2::new(Vector2::new(1.0, 2.0), Vector2::new(3.0, 4.0));
565 let v2 = Vector2::new(2.0, 3.0);
566 assert_eq!(m2.mdot(&v2), Vector2::new(8.0, 18.0));
567 }
568
569 #[test]
570 fn test_scale() {
571 let m = Matrix2::new(Vector2::new(3, 4), Vector2::new(5, 6));
572 assert_eq!(
573 m.scale(2),
574 Matrix2::new(Vector2::new(6, 8), Vector2::new(10, 12))
575 );
576
577 let m2 = Matrix2::new(Vector2::new(1.5, 2.5), Vector2::new(3.5, 4.5));
578 assert_eq!(
579 m2.scale(2.0),
580 Matrix2::new(Vector2::new(3.0, 5.0), Vector2::new(7.0, 9.0))
581 );
582 }
583
584 #[test]
585 fn test_unscale() {
586 let m = Matrix2::new(Vector2::new(30, 40), Vector2::new(50, 60));
587 assert_eq!(
588 m.unscale(10),
589 Matrix2::new(Vector2::new(3, 4), Vector2::new(5, 6))
590 );
591
592 let m2 = Matrix2::new(Vector2::new(3.0, 5.0), Vector2::new(7.0, 9.0));
593 assert_eq!(
594 m2.unscale(2.0),
595 Matrix2::new(Vector2::new(1.5, 2.5), Vector2::new(3.5, 4.5))
596 );
597 }
598
599 #[test]
600 fn test_add() {
601 let m1 = Matrix2::new(Vector2::new(1, 2), Vector2::new(3, 4));
602 let m2 = Matrix2::new(Vector2::new(5, 6), Vector2::new(7, 8));
603 assert_eq!(
604 m1 + m2,
605 Matrix2::new(Vector2::new(6, 8), Vector2::new(10, 12))
606 );
607
608 let m3 = m1 + m2;
609 assert_eq!(m3, Matrix2::new(Vector2::new(6, 8), Vector2::new(10, 12)));
610
611 let m4 = m1 + m2;
612 assert_eq!(m4, Matrix2::new(Vector2::new(6, 8), Vector2::new(10, 12)));
613 }
614
615 #[test]
616 fn test_sub() {
617 let m1 = Matrix2::new(Vector2::new(5, 6), Vector2::new(7, 8));
618 let m2 = Matrix2::new(Vector2::new(1, 2), Vector2::new(3, 4));
619 assert_eq!(
620 m1 - m2,
621 Matrix2::new(Vector2::new(4, 4), Vector2::new(4, 4))
622 );
623
624 let m3 = m1 - m2;
625 assert_eq!(m3, Matrix2::new(Vector2::new(4, 4), Vector2::new(4, 4)));
626 }
627
628 #[test]
629 fn test_neg() {
630 let m = Matrix2::new(Vector2::new(1, -2), Vector2::new(-3, 4));
631 assert_eq!(-m, Matrix2::new(Vector2::new(-1, 2), Vector2::new(3, -4)));
632 assert_eq!(-&m, Matrix2::new(Vector2::new(-1, 2), Vector2::new(3, -4)));
633 }
634
635 #[test]
636 fn test_scalar_mul() {
637 let m = Matrix2::new(Vector2::new(2, 3), Vector2::new(4, 5));
638 assert_eq!(
639 m * 4,
640 Matrix2::new(Vector2::new(8, 12), Vector2::new(16, 20))
641 );
642 assert_eq!(
643 &m * 4,
644 Matrix2::new(Vector2::new(8, 12), Vector2::new(16, 20))
645 );
646 assert_eq!(
647 4 * m,
648 Matrix2::new(Vector2::new(8, 12), Vector2::new(16, 20))
649 );
650 assert_eq!(
651 4 * &m,
652 Matrix2::new(Vector2::new(8, 12), Vector2::new(16, 20))
653 );
654 }
655
656 #[test]
657 fn test_scalar_div() {
658 let m = Matrix2::new(Vector2::new(10, 20), Vector2::new(30, 40));
659 assert_eq!(m / 5, Matrix2::new(Vector2::new(2, 4), Vector2::new(6, 8)));
660 }
661
662 #[test]
663 fn test_scalar_rem() {
664 let m = Matrix2::new(Vector2::new(10, 21), Vector2::new(32, 43));
665 assert_eq!(m % 3, Matrix2::new(Vector2::new(1, 0), Vector2::new(2, 1)));
666 }
667
668 #[test]
669 fn test_zero() {
670 let zero = Matrix2::<i32>::zero();
671 assert_eq!(zero, Matrix2::new(Vector2::zero(), Vector2::zero()));
672 assert!(zero.is_zero());
673
674 let mut m = Matrix2::new(Vector2::new(1, 2), Vector2::new(3, 4));
675 assert!(!m.is_zero());
676 m.set_zero();
677 assert!(m.is_zero());
678 }
679
680 #[test]
681 fn test_add_assign() {
682 let mut m1 = Matrix2::new(Vector2::new(1, 2), Vector2::new(3, 4));
683 let m2 = Matrix2::new(Vector2::new(5, 6), Vector2::new(7, 8));
684 m1 += m2;
685 assert_eq!(m1, Matrix2::new(Vector2::new(6, 8), Vector2::new(10, 12)));
686
687 let mut m3 = Matrix2::new(Vector2::new(1, 2), Vector2::new(3, 4));
688 m3 += &m2;
689 assert_eq!(m3, Matrix2::new(Vector2::new(6, 8), Vector2::new(10, 12)));
690 }
691
692 #[test]
693 fn test_sub_assign() {
694 let mut m1 = Matrix2::new(Vector2::new(5, 6), Vector2::new(7, 8));
695 let m2 = Matrix2::new(Vector2::new(1, 2), Vector2::new(3, 4));
696 m1 -= m2;
697 assert_eq!(m1, Matrix2::new(Vector2::new(4, 4), Vector2::new(4, 4)));
698
699 let mut m3 = Matrix2::new(Vector2::new(5, 6), Vector2::new(7, 8));
700 m3 -= &m2;
701 assert_eq!(m3, Matrix2::new(Vector2::new(4, 4), Vector2::new(4, 4)));
702 }
703
704 #[test]
705 fn test_mul_assign() {
706 let mut m = Matrix2::new(Vector2::new(1, 2), Vector2::new(3, 4));
707 m *= 3;
708 assert_eq!(m, Matrix2::new(Vector2::new(3, 6), Vector2::new(9, 12)));
709
710 let mut m2 = Matrix2::new(Vector2::new(1, 2), Vector2::new(3, 4));
711 let scalar = 3;
712 m2 *= &scalar;
713 assert_eq!(m2, Matrix2::new(Vector2::new(3, 6), Vector2::new(9, 12)));
714 }
715
716 #[test]
717 fn test_div_assign() {
718 let mut m = Matrix2::new(Vector2::new(6, 9), Vector2::new(12, 15));
719 m /= 3;
720 assert_eq!(m, Matrix2::new(Vector2::new(2, 3), Vector2::new(4, 5)));
721
722 let mut m2 = Matrix2::new(Vector2::new(6, 9), Vector2::new(12, 15));
723 let scalar = 3;
724 m2 /= &scalar;
725 assert_eq!(m2, Matrix2::new(Vector2::new(2, 3), Vector2::new(4, 5)));
726 }
727
728 #[test]
729 fn test_float_operations() {
730 let m = Matrix2::new(Vector2::new(1.5, 2.5), Vector2::new(3.5, 4.5));
731 assert_eq!(
732 m.scale(2.0),
733 Matrix2::new(Vector2::new(3.0, 5.0), Vector2::new(7.0, 9.0))
734 );
735 assert_eq!(
736 m.unscale(0.5),
737 Matrix2::new(Vector2::new(3.0, 5.0), Vector2::new(7.0, 9.0))
738 );
739 assert_eq!(m.det(), 1.5 * 4.5 - 2.5 * 3.5);
740 }
741
742 #[test]
743 fn test_clone_and_eq() {
744 let m1 = Matrix2::new(Vector2::new(1, 2), Vector2::new(3, 4));
745 let m2 = m1;
746 assert_eq!(m1, m2);
747
748 let m3 = Matrix2::new(Vector2::new(2, 1), Vector2::new(4, 3));
749 assert_ne!(m1, m3);
750 }
751
752 #[test]
753 fn test_debug() {
754 let m = Matrix2::new(Vector2::new(1, 2), Vector2::new(3, 4));
755 assert_eq!(
756 format!("{:?}", m),
757 "Matrix2 { x_: Vector2 { x_: 1, y_: 2 }, y_: Vector2 { x_: 3, y_: 4 } }"
758 );
759 }
760
761 #[test]
762 fn test_forward_xf_val_binop() {
763 let m1 = Matrix2::new(Vector2::new(1, 2), Vector2::new(3, 4));
764 let m2 = Matrix2::new(Vector2::new(5, 6), Vector2::new(7, 8));
765 let result: Matrix2<i32> = m1 + m2;
766 assert_eq!(
767 result,
768 Matrix2::new(Vector2::new(6, 8), Vector2::new(10, 12))
769 );
770 }
771
772 #[test]
773 fn test_forward_val_xf_binop() {
774 let m1 = Matrix2::new(Vector2::new(1, 2), Vector2::new(3, 4));
775 let m2 = Matrix2::new(Vector2::new(5, 6), Vector2::new(7, 8));
776 let result: Matrix2<i32> = m1 + m2;
777 assert_eq!(
778 result,
779 Matrix2::new(Vector2::new(6, 8), Vector2::new(10, 12))
780 );
781 }
782
783 #[test]
784 fn test_scalar_arithmetic_forward() {
785 let m = Matrix2::new(Vector2::new(2, 3), Vector2::new(4, 5));
786 let scalar = 3;
787 let result: Matrix2<i32> = m * scalar;
788 assert_eq!(
789 result,
790 Matrix2::new(Vector2::new(6, 9), Vector2::new(12, 15))
791 );
792
793 let result2: Matrix2<i32> = m * scalar;
794 assert_eq!(
795 result2,
796 Matrix2::new(Vector2::new(6, 9), Vector2::new(12, 15))
797 );
798
799 let result3: Matrix2<i32> = 3 * &m;
800 assert_eq!(
801 result3,
802 Matrix2::new(Vector2::new(6, 9), Vector2::new(12, 15))
803 );
804 }
805
806 #[test]
807 fn test_scalar_left_mul() {
808 let m = Matrix2::new(Vector2::new(2, 3), Vector2::new(4, 5));
809 assert_eq!(
810 3 * m,
811 Matrix2::new(Vector2::new(6, 9), Vector2::new(12, 15))
812 );
813 assert_eq!(
814 3 * &m,
815 Matrix2::new(Vector2::new(6, 9), Vector2::new(12, 15))
816 );
817 }
818
819 #[test]
820 fn test_scalar_mul_by_ref_matrix() {
821 let m = Matrix2::new(Vector2::new(1, 2), Vector2::new(3, 4));
822 assert_eq!(
823 5 * &m,
824 Matrix2::new(Vector2::new(5, 10), Vector2::new(15, 20))
825 );
826 }
827}