From 5b7af11555615c28f6e3bf855fc5aa5a44a853b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Crozet?= Date: Mon, 28 Mar 2016 15:18:28 +0200 Subject: [PATCH] Add Sim/Rot, Sim/Iso, Iso/Rot multiplications. --- src/structs/iso.rs | 6 ++-- src/structs/iso_macros.rs | 48 ++++++++++++++++++---------- src/structs/sim.rs | 8 ++--- src/structs/sim_macros.rs | 66 ++++++++++++++++++++++++++++++++++----- tests/transforms.rs | 48 ++++++++++++++++++++-------- 5 files changed, 132 insertions(+), 44 deletions(-) diff --git a/src/structs/iso.rs b/src/structs/iso.rs index decbdf6d..e401fa7f 100644 --- a/src/structs/iso.rs +++ b/src/structs/iso.rs @@ -95,10 +95,9 @@ rotate_impl!(Iso2, Vec2); translation_impl!(Iso2, Vec2); translate_impl!(Iso2, Pnt2); iso_mul_iso_impl!(Iso2); +iso_mul_rot_impl!(Iso2, Rot2); iso_mul_pnt_impl!(Iso2, Pnt2); -pnt_mul_iso_impl!(Iso2, Pnt2); iso_mul_vec_impl!(Iso2, Vec2); -vec_mul_iso_impl!(Iso2, Vec2); arbitrary_iso_impl!(Iso2); iso_display_impl!(Iso2); @@ -118,9 +117,8 @@ rotate_impl!(Iso3, Vec3); translation_impl!(Iso3, Vec3); translate_impl!(Iso3, Pnt3); iso_mul_iso_impl!(Iso3); +iso_mul_rot_impl!(Iso3, Rot3); iso_mul_pnt_impl!(Iso3, Pnt3); -pnt_mul_iso_impl!(Iso3, Pnt3); iso_mul_vec_impl!(Iso3, Vec3); -vec_mul_iso_impl!(Iso3, Vec3); arbitrary_iso_impl!(Iso3); iso_display_impl!(Iso3); diff --git a/src/structs/iso_macros.rs b/src/structs/iso_macros.rs index c5f42099..ccb778ee 100644 --- a/src/structs/iso_macros.rs +++ b/src/structs/iso_macros.rs @@ -76,6 +76,30 @@ macro_rules! iso_mul_iso_impl( ) ); +macro_rules! iso_mul_rot_impl( + ($t: ident, $tr: ident) => ( + impl Mul<$tr> for $t { + type Output = $t; + + #[inline] + fn mul(self, right: $tr) -> $t { + $t::new_with_rotmat(self.translation, self.rotation * right) + } + } + + impl Mul<$t> for $tr { + type Output = $t; + + #[inline] + fn mul(self, right: $t) -> $t { + $t::new_with_rotmat( + self * right.translation, + self * right.rotation) + } + } + ) +); + macro_rules! iso_mul_pnt_impl( ($t: ident, $tv: ident) => ( impl Mul<$tv> for $t { @@ -86,6 +110,14 @@ macro_rules! iso_mul_pnt_impl( self.rotation * right + self.translation } } + + impl Mul<$t> for $tv { + type Output = $tv; + #[inline] + fn mul(self, right: $t) -> $tv { + (self + right.translation) * right.rotation + } + } ) ); @@ -99,23 +131,7 @@ macro_rules! iso_mul_vec_impl( self.rotation * right } } - ) -); -macro_rules! pnt_mul_iso_impl( - ($t: ident, $tv: ident) => ( - impl Mul<$t> for $tv { - type Output = $tv; - #[inline] - fn mul(self, right: $t) -> $tv { - (self + right.translation) * right.rotation - } - } - ) -); - -macro_rules! vec_mul_iso_impl( - ($t: ident, $tv: ident) => ( impl Mul<$t> for $tv { type Output = $tv; #[inline] diff --git a/src/structs/sim.rs b/src/structs/sim.rs index dd7d32f1..e2f0a183 100644 --- a/src/structs/sim.rs +++ b/src/structs/sim.rs @@ -54,10 +54,10 @@ dim_impl!(Sim2, 2); sim_scale_impl!(Sim2); sim_one_impl!(Sim2); sim_mul_sim_impl!(Sim2); +sim_mul_iso_impl!(Sim2, Iso2); +sim_mul_rot_impl!(Sim2, Rot2); sim_mul_pnt_vec_impl!(Sim2, Pnt2); -pnt_vec_mul_sim_impl!(Sim2, Pnt2); sim_mul_pnt_vec_impl!(Sim2, Vec2); -pnt_vec_mul_sim_impl!(Sim2, Vec2); transformation_impl!(Sim2); sim_transform_impl!(Sim2, Pnt2); sim_inv_impl!(Sim2); @@ -72,10 +72,10 @@ dim_impl!(Sim3, 3); sim_scale_impl!(Sim3); sim_one_impl!(Sim3); sim_mul_sim_impl!(Sim3); +sim_mul_iso_impl!(Sim3, Iso3); +sim_mul_rot_impl!(Sim3, Rot3); sim_mul_pnt_vec_impl!(Sim3, Pnt3); -pnt_vec_mul_sim_impl!(Sim3, Pnt3); sim_mul_pnt_vec_impl!(Sim3, Vec3); -pnt_vec_mul_sim_impl!(Sim3, Vec3); transformation_impl!(Sim3); sim_transform_impl!(Sim3, Pnt3); sim_inv_impl!(Sim3); diff --git a/src/structs/sim_macros.rs b/src/structs/sim_macros.rs index 29c575ad..97ad7bfa 100644 --- a/src/structs/sim_macros.rs +++ b/src/structs/sim_macros.rs @@ -126,6 +126,62 @@ macro_rules! sim_mul_sim_impl( ) ); +macro_rules! sim_mul_iso_impl( + ($t: ident, $ti: ident) => ( + impl Mul<$ti> for $t { + type Output = $t; + + #[inline] + fn mul(self, right: $ti) -> $t { + $t::new_with_rotmat( + self.isometry.translation + self.isometry.rotation * (right.translation * self.scale), + self.isometry.rotation * right.rotation, + self.scale) + } + } + + impl Mul<$t> for $ti { + type Output = $t; + + #[inline] + fn mul(self, right: $t) -> $t { + $t::new_with_rotmat( + self.translation + self.rotation * right.isometry.translation, + self.rotation * right.isometry.rotation, + right.scale) + } + } + ) +); + +macro_rules! sim_mul_rot_impl( + ($t: ident, $tr: ident) => ( + impl Mul<$tr> for $t { + type Output = $t; + + #[inline] + fn mul(self, right: $tr) -> $t { + $t::new_with_rotmat( + self.isometry.translation, + self.isometry.rotation * right, + self.scale) + } + } + + impl Mul<$t> for $tr { + type Output = $t; + + #[inline] + fn mul(self, right: $t) -> $t { + $t::new_with_rotmat( + self * right.isometry.translation, + self * right.isometry.rotation, + right.scale) + } + } + ) +); + macro_rules! sim_mul_pnt_vec_impl( ($t: ident, $tv: ident) => ( impl Mul<$tv> for $t { @@ -133,19 +189,15 @@ macro_rules! sim_mul_pnt_vec_impl( #[inline] fn mul(self, right: $tv) -> $tv { - self.isometry * (right * self.scale) + (self.isometry * right) * self.scale } } - ) -); -macro_rules! pnt_vec_mul_sim_impl( - ($t: ident, $tv: ident) => ( impl Mul<$t> for $tv { type Output = $tv; #[inline] fn mul(self, right: $t) -> $tv { - self * right.isometry * right.scale + (self * right.scale) * right.isometry } } ) @@ -161,7 +213,7 @@ macro_rules! sim_transform_impl( #[inline] fn inv_transform(&self, p: &$tp) -> $tp { - self.isometry.inv_transform(p) / self.scale + self.isometry.inv_transform(&(*p / self.scale)) } } ) diff --git a/tests/transforms.rs b/tests/transforms.rs index 1b1fa6c9..7a109d64 100644 --- a/tests/transforms.rs +++ b/tests/transforms.rs @@ -2,30 +2,22 @@ extern crate nalgebra as na; extern crate rand; use rand::random; -use na::{Pnt3, Vec3, Vec1, Rot2, Rot3, Persp3, PerspMat3, Ortho3, OrthoMat3, Iso2, Iso3, BaseFloat, - Sim2, Sim3}; +use na::{Pnt2, Pnt3, Vec3, Vec1, Rot2, Rot3, Persp3, PerspMat3, Ortho3, OrthoMat3, Iso2, Iso3, + Sim2, Sim3, BaseFloat, Transform}; macro_rules! test_transform_inv_transform_impl( ($t: ty, $p: ty) => ( for _ in 0usize .. 10000 { let randmat: $t = random(); - let randvec: $p = random(); + let expected: $p = random(); - let tvec = randmat.transform(&randvec); - let original = randmat.inv_transform(&randvec); + let computed = randmat.inv_transform(&randmat.transform(&expected)); - assert!(na::approx_eq(&randvec, &original)); + assert!(na::approx_eq(&computed, &expected)); } ); ); -test_transform_inv_transform_impl!(Rot2, Pnt2); -test_transform_inv_transform_impl!(Rot3, Pnt3); -test_transform_inv_transform_impl!(Iso2, Pnt2); -test_transform_inv_transform_impl!(Iso3, Pnt3); -test_transform_inv_transform_impl!(Sim2, Pnt2); -test_transform_inv_transform_impl!(Sim3, Pnt3); - #[test] fn test_rotation2() { for _ in 0usize .. 10000 { @@ -218,3 +210,33 @@ fn test_ortho() { assert!(na::approx_eq(&pm.znear(), &24.0)); assert!(na::approx_eq(&pm.zfar(), &61.0)); } + +#[test] +fn test_transform_inv_transform_rot2() { + test_transform_inv_transform_impl!(Rot2, Pnt2); +} + +#[test] +fn test_transform_inv_transform_rot3() { + test_transform_inv_transform_impl!(Rot3, Pnt3); +} + +#[test] +fn test_transform_inv_transform_iso2() { + test_transform_inv_transform_impl!(Iso2, Pnt2); +} + +#[test] +fn test_transform_inv_transform_iso3() { + test_transform_inv_transform_impl!(Iso3, Pnt3); +} + +#[test] +fn test_transform_inv_transform_sim2() { + test_transform_inv_transform_impl!(Sim2, Pnt2); +} + +#[test] +fn test_transform_inv_transform_sim3() { + test_transform_inv_transform_impl!(Sim3, Pnt3); +}