diff --git a/src/quaternion.rs b/src/quaternion.rs index a20690d..b249960 100644 --- a/src/quaternion.rs +++ b/src/quaternion.rs @@ -167,6 +167,31 @@ impl_operator!( Mul > for Quaternion { } }); +macro_rules! impl_scalar_mul { + ($S:ident) => { + impl_operator!(Mul> for $S { + fn mul(scalar, quat) -> Quaternion<$S> { + Quaternion::from_sv(scalar * quat.s, scalar * quat.v) + } + }); + }; +} + +macro_rules! impl_scalar_div { + ($S:ident) => { + impl_operator!(Div> for $S { + fn div(scalar, quat) -> Quaternion<$S> { + Quaternion::from_sv(scalar / quat.s, scalar / quat.v) + } + }); + }; +} + +impl_scalar_mul!(f32); +impl_scalar_mul!(f64); +impl_scalar_div!(f32); +impl_scalar_div!(f64); + impl ApproxEq for Quaternion { type Epsilon = S; diff --git a/tests/quaternion.rs b/tests/quaternion.rs index e97abab..effa31e 100644 --- a/tests/quaternion.rs +++ b/tests/quaternion.rs @@ -16,6 +16,42 @@ #[macro_use] extern crate cgmath; +macro_rules! impl_test_mul { + ($s:expr, $v:expr) => ( + // point * scalar ops + assert_eq!($v * $s, Quaternion::from_sv($v.s * $s, $v.v * $s)); + assert_eq!($s * $v, Quaternion::from_sv($s * $v.s, $s * $v.v)); + assert_eq!(&$v * $s, $v * $s); + assert_eq!($s * &$v, $s * $v); + // commutativity + assert_eq!($v * $s, $s * $v); + ) +} + +macro_rules! impl_test_div { + ($s:expr, $v:expr) => ( + // point / scalar ops + assert_eq!($v / $s, Quaternion::from_sv($v.s / $s, $v.v / $s)); + assert_eq!($s / $v, Quaternion::from_sv($s / $v.s, $s / $v.v)); + assert_eq!(&$v / $s, $v / $s); + assert_eq!($s / &$v, $s / $v); + ) +} + +mod operators { + use cgmath::*; + + #[test] + fn test_mul() { + impl_test_mul!(2.0f32, Quaternion::from_euler(rad(1f32), rad(1f32), rad(1f32))); + } + + #[test] + fn test_div() { + impl_test_div!(2.0f32, Quaternion::from_euler(rad(1f32), rad(1f32), rad(1f32))); + } +} + mod to_from_euler { use std::f32;