From 24a21d5fc6b567d6bd02405b9ac4b3af4c1a055a Mon Sep 17 00:00:00 2001 From: Cameron Hart Date: Sat, 2 Jan 2016 16:11:16 +1100 Subject: [PATCH] Added scalar arithmetic operators for Matrix types --- src/matrix.rs | 27 +++++++++++++ tests/matrix.rs | 100 ++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 115 insertions(+), 12 deletions(-) diff --git a/src/matrix.rs b/src/matrix.rs index 6287ebe..ca908f2 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -859,9 +859,36 @@ macro_rules! impl_operators { impl_operator!( Mul<$VectorN > for $MatrixN { fn mul(matrix, vector) -> $VectorN { $VectorN::new($(matrix.row($row_index).dot(vector.clone())),+) } }); + + impl_scalar_ops!($MatrixN { $($field),+ }); + impl_scalar_ops!($MatrixN { $($field),+ }); + impl_scalar_ops!($MatrixN { $($field),+ }); + impl_scalar_ops!($MatrixN { $($field),+ }); + impl_scalar_ops!($MatrixN { $($field),+ }); + impl_scalar_ops!($MatrixN { $($field),+ }); + impl_scalar_ops!($MatrixN { $($field),+ }); + impl_scalar_ops!($MatrixN { $($field),+ }); + impl_scalar_ops!($MatrixN { $($field),+ }); + impl_scalar_ops!($MatrixN { $($field),+ }); + impl_scalar_ops!($MatrixN { $($field),+ }); + impl_scalar_ops!($MatrixN { $($field),+ }); } } +macro_rules! impl_scalar_ops { + ($MatrixN:ident<$S:ident> { $($field:ident),+ }) => { + impl_operator!(Mul<$MatrixN<$S>> for $S { + fn mul(scalar, matrix) -> $MatrixN<$S> { $MatrixN { $($field: scalar * matrix.$field),+ } } + }); + impl_operator!(Div<$MatrixN<$S>> for $S { + fn div(scalar, matrix) -> $MatrixN<$S> { $MatrixN { $($field: scalar / matrix.$field),+ } } + }); + impl_operator!(Rem<$MatrixN<$S>> for $S { + fn rem(scalar, matrix) -> $MatrixN<$S> { $MatrixN { $($field: scalar % matrix.$field),+ } } + }); + }; +} + impl_operators!(Matrix2, Vector2 { x: 0, y: 1 }); impl_operators!(Matrix3, Vector3 { x: 0, y: 1, z: 2 }); impl_operators!(Matrix4, Vector4 { x: 0, y: 1, z: 2, w: 3 }); diff --git a/tests/matrix.rs b/tests/matrix.rs index aa17439..81b4ab9 100644 --- a/tests/matrix.rs +++ b/tests/matrix.rs @@ -40,9 +40,30 @@ pub mod matrix2 { #[test] fn test_mul_scalar() { - assert_eq!(A * F, - Matrix2::new(0.5f64, 1.5f64, - 1.0f64, 2.0f64)); + let result = Matrix2::new(0.5f64, 1.5f64, + 1.0f64, 2.0f64) ; + assert_eq!(A * F, result); + assert_eq!(F * A, result); + } + + #[test] + fn test_div_scalar() { + assert_eq!(A / F, + Matrix2::new(2.0f64, 6.0f64, + 4.0f64, 8.0f64)); + assert_eq!(4.0f64 / C, + Matrix2::new(2.0f64, 4.0f64, + 4.0f64, 2.0f64)); + } + + #[test] + fn test_rem_scalar() { + assert_eq!(A % 3.0f64, + Matrix2::new(1.0f64, 0.0f64, + 2.0f64, 1.0f64)); + assert_eq!(3.0f64 % A, + Matrix2::new(0.0f64, 0.0f64, + 1.0f64, 3.0f64)); } #[test] @@ -169,6 +190,7 @@ pub mod matrix3 { const V: Vector3 = Vector3 { x: 1.0f64, y: 2.0f64, z: 3.0f64 }; const F: f64 = 0.5; + const G: f64 = 6.0; #[test] fn test_neg() { @@ -180,10 +202,35 @@ pub mod matrix3 { #[test] fn test_mul_scalar() { - assert_eq!(A * F, - Matrix3::new(0.5f64, 2.0f64, 3.5f64, - 1.0f64, 2.5f64, 4.0f64, - 1.5f64, 3.0f64, 4.5f64)); + let result = Matrix3::new(0.5f64, 2.0f64, 3.5f64, + 1.0f64, 2.5f64, 4.0f64, + 1.5f64, 3.0f64, 4.5f64); + assert_eq!(A * F, result); + assert_eq!(F * A, result); + } + + #[test] + fn test_div_scalar() { + assert_eq!(A / F, + Matrix3::new(2.0f64, 8.0f64, 14.0f64, + 4.0f64, 10.0f64, 16.0f64, + 6.0f64, 12.0f64, 18.0f64)); + assert_eq!(G / D, + Matrix3::new(2.0f64, 3.0f64, 6.0f64, + 3.0f64, 2.0f64, 3.0f64, + 6.0f64, 3.0f64, 2.0f64)); + } + + #[test] + fn test_rem_scalar() { + assert_eq!(A % 3.0f64, + Matrix3::new(1.0f64, 1.0f64, 1.0f64, + 2.0f64, 2.0f64, 2.0f64, + 0.0f64, 0.0f64, 0.0f64)); + assert_eq!(9.0f64 % A, + Matrix3::new(0.0f64, 1.0f64, 2.0f64, + 1.0f64, 4.0f64, 1.0f64, + 0.0f64, 3.0f64, 0.0f64)); } #[test] @@ -402,11 +449,40 @@ pub mod matrix4 { #[test] fn test_mul_scalar() { - assert_eq!(A * F, - Matrix4::new(0.5f64, 2.5f64, 4.5f64, 6.5f64, - 1.0f64, 3.0f64, 5.0f64, 7.0f64, - 1.5f64, 3.5f64, 5.5f64, 7.5f64, - 2.0f64, 4.0f64, 6.0f64, 8.0f64)); + let result = Matrix4::new(0.5f64, 2.5f64, 4.5f64, 6.5f64, + 1.0f64, 3.0f64, 5.0f64, 7.0f64, + 1.5f64, 3.5f64, 5.5f64, 7.5f64, + 2.0f64, 4.0f64, 6.0f64, 8.0f64); + assert_eq!(A * F, result); + assert_eq!(F * A, result); + } + + #[test] + fn test_div_scalar() { + assert_eq!(A / F, + Matrix4::new(2.0f64, 10.0f64, 18.0f64, 26.0f64, + 4.0f64, 12.0f64, 20.0f64, 28.0f64, + 6.0f64, 14.0f64, 22.0f64, 30.0f64, + 8.0f64, 16.0f64, 24.0f64, 32.0f64)); + assert_eq!(12.0f64 / D, + Matrix4::new( 3.0f64, 4.0f64, 6.0f64, 12.0f64, + 4.0f64, 3.0f64, 4.0f64, 6.0f64, + 6.0f64, 4.0f64, 3.0f64, 4.0f64, + 12.0f64, 6.0f64, 4.0f64, 3.0f64)); + } + + #[test] + fn test_rem_scalar() { + assert_eq!(A % 4.0f64, + Matrix4::new(1.0f64, 1.0f64, 1.0f64, 1.0f64, + 2.0f64, 2.0f64, 2.0f64, 2.0f64, + 3.0f64, 3.0f64, 3.0f64, 3.0f64, + 0.0f64, 0.0f64, 0.0f64, 0.0f64)); + assert_eq!(16.0f64 % A, + Matrix4::new(0.0f64, 1.0f64, 7.0f64, 3.0f64, + 0.0f64, 4.0f64, 6.0f64, 2.0f64, + 1.0f64, 2.0f64, 5.0f64, 1.0f64, + 0.0f64, 0.0f64, 4.0f64, 0.0f64)); } #[test]