Add Sim/Rot, Sim/Iso, Iso/Rot multiplications.

This commit is contained in:
Sébastien Crozet 2016-03-28 15:18:28 +02:00
parent 02001667f7
commit 5b7af11555
5 changed files with 132 additions and 44 deletions

View File

@ -95,10 +95,9 @@ rotate_impl!(Iso2, Vec2);
translation_impl!(Iso2, Vec2); translation_impl!(Iso2, Vec2);
translate_impl!(Iso2, Pnt2); translate_impl!(Iso2, Pnt2);
iso_mul_iso_impl!(Iso2); iso_mul_iso_impl!(Iso2);
iso_mul_rot_impl!(Iso2, Rot2);
iso_mul_pnt_impl!(Iso2, Pnt2); iso_mul_pnt_impl!(Iso2, Pnt2);
pnt_mul_iso_impl!(Iso2, Pnt2);
iso_mul_vec_impl!(Iso2, Vec2); iso_mul_vec_impl!(Iso2, Vec2);
vec_mul_iso_impl!(Iso2, Vec2);
arbitrary_iso_impl!(Iso2); arbitrary_iso_impl!(Iso2);
iso_display_impl!(Iso2); iso_display_impl!(Iso2);
@ -118,9 +117,8 @@ rotate_impl!(Iso3, Vec3);
translation_impl!(Iso3, Vec3); translation_impl!(Iso3, Vec3);
translate_impl!(Iso3, Pnt3); translate_impl!(Iso3, Pnt3);
iso_mul_iso_impl!(Iso3); iso_mul_iso_impl!(Iso3);
iso_mul_rot_impl!(Iso3, Rot3);
iso_mul_pnt_impl!(Iso3, Pnt3); iso_mul_pnt_impl!(Iso3, Pnt3);
pnt_mul_iso_impl!(Iso3, Pnt3);
iso_mul_vec_impl!(Iso3, Vec3); iso_mul_vec_impl!(Iso3, Vec3);
vec_mul_iso_impl!(Iso3, Vec3);
arbitrary_iso_impl!(Iso3); arbitrary_iso_impl!(Iso3);
iso_display_impl!(Iso3); iso_display_impl!(Iso3);

View File

@ -76,6 +76,30 @@ macro_rules! iso_mul_iso_impl(
) )
); );
macro_rules! iso_mul_rot_impl(
($t: ident, $tr: ident) => (
impl<N: BaseFloat> Mul<$tr<N>> for $t<N> {
type Output = $t<N>;
#[inline]
fn mul(self, right: $tr<N>) -> $t<N> {
$t::new_with_rotmat(self.translation, self.rotation * right)
}
}
impl<N: BaseFloat> Mul<$t<N>> for $tr<N> {
type Output = $t<N>;
#[inline]
fn mul(self, right: $t<N>) -> $t<N> {
$t::new_with_rotmat(
self * right.translation,
self * right.rotation)
}
}
)
);
macro_rules! iso_mul_pnt_impl( macro_rules! iso_mul_pnt_impl(
($t: ident, $tv: ident) => ( ($t: ident, $tv: ident) => (
impl<N: BaseNum> Mul<$tv<N>> for $t<N> { impl<N: BaseNum> Mul<$tv<N>> for $t<N> {
@ -86,6 +110,14 @@ macro_rules! iso_mul_pnt_impl(
self.rotation * right + self.translation self.rotation * right + self.translation
} }
} }
impl<N: BaseNum> Mul<$t<N>> for $tv<N> {
type Output = $tv<N>;
#[inline]
fn mul(self, right: $t<N>) -> $tv<N> {
(self + right.translation) * right.rotation
}
}
) )
); );
@ -99,23 +131,7 @@ macro_rules! iso_mul_vec_impl(
self.rotation * right self.rotation * right
} }
} }
)
);
macro_rules! pnt_mul_iso_impl(
($t: ident, $tv: ident) => (
impl<N: BaseNum> Mul<$t<N>> for $tv<N> {
type Output = $tv<N>;
#[inline]
fn mul(self, right: $t<N>) -> $tv<N> {
(self + right.translation) * right.rotation
}
}
)
);
macro_rules! vec_mul_iso_impl(
($t: ident, $tv: ident) => (
impl<N: BaseNum> Mul<$t<N>> for $tv<N> { impl<N: BaseNum> Mul<$t<N>> for $tv<N> {
type Output = $tv<N>; type Output = $tv<N>;
#[inline] #[inline]

View File

@ -54,10 +54,10 @@ dim_impl!(Sim2, 2);
sim_scale_impl!(Sim2); sim_scale_impl!(Sim2);
sim_one_impl!(Sim2); sim_one_impl!(Sim2);
sim_mul_sim_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); sim_mul_pnt_vec_impl!(Sim2, Pnt2);
pnt_vec_mul_sim_impl!(Sim2, Pnt2);
sim_mul_pnt_vec_impl!(Sim2, Vec2); sim_mul_pnt_vec_impl!(Sim2, Vec2);
pnt_vec_mul_sim_impl!(Sim2, Vec2);
transformation_impl!(Sim2); transformation_impl!(Sim2);
sim_transform_impl!(Sim2, Pnt2); sim_transform_impl!(Sim2, Pnt2);
sim_inv_impl!(Sim2); sim_inv_impl!(Sim2);
@ -72,10 +72,10 @@ dim_impl!(Sim3, 3);
sim_scale_impl!(Sim3); sim_scale_impl!(Sim3);
sim_one_impl!(Sim3); sim_one_impl!(Sim3);
sim_mul_sim_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); sim_mul_pnt_vec_impl!(Sim3, Pnt3);
pnt_vec_mul_sim_impl!(Sim3, Pnt3);
sim_mul_pnt_vec_impl!(Sim3, Vec3); sim_mul_pnt_vec_impl!(Sim3, Vec3);
pnt_vec_mul_sim_impl!(Sim3, Vec3);
transformation_impl!(Sim3); transformation_impl!(Sim3);
sim_transform_impl!(Sim3, Pnt3); sim_transform_impl!(Sim3, Pnt3);
sim_inv_impl!(Sim3); sim_inv_impl!(Sim3);

View File

@ -126,6 +126,62 @@ macro_rules! sim_mul_sim_impl(
) )
); );
macro_rules! sim_mul_iso_impl(
($t: ident, $ti: ident) => (
impl<N: BaseFloat> Mul<$ti<N>> for $t<N> {
type Output = $t<N>;
#[inline]
fn mul(self, right: $ti<N>) -> $t<N> {
$t::new_with_rotmat(
self.isometry.translation + self.isometry.rotation * (right.translation * self.scale),
self.isometry.rotation * right.rotation,
self.scale)
}
}
impl<N: BaseFloat> Mul<$t<N>> for $ti<N> {
type Output = $t<N>;
#[inline]
fn mul(self, right: $t<N>) -> $t<N> {
$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<N: BaseFloat> Mul<$tr<N>> for $t<N> {
type Output = $t<N>;
#[inline]
fn mul(self, right: $tr<N>) -> $t<N> {
$t::new_with_rotmat(
self.isometry.translation,
self.isometry.rotation * right,
self.scale)
}
}
impl<N: BaseFloat> Mul<$t<N>> for $tr<N> {
type Output = $t<N>;
#[inline]
fn mul(self, right: $t<N>) -> $t<N> {
$t::new_with_rotmat(
self * right.isometry.translation,
self * right.isometry.rotation,
right.scale)
}
}
)
);
macro_rules! sim_mul_pnt_vec_impl( macro_rules! sim_mul_pnt_vec_impl(
($t: ident, $tv: ident) => ( ($t: ident, $tv: ident) => (
impl<N: BaseNum> Mul<$tv<N>> for $t<N> { impl<N: BaseNum> Mul<$tv<N>> for $t<N> {
@ -133,19 +189,15 @@ macro_rules! sim_mul_pnt_vec_impl(
#[inline] #[inline]
fn mul(self, right: $tv<N>) -> $tv<N> { fn mul(self, right: $tv<N>) -> $tv<N> {
self.isometry * (right * self.scale) (self.isometry * right) * self.scale
} }
} }
)
);
macro_rules! pnt_vec_mul_sim_impl(
($t: ident, $tv: ident) => (
impl<N: BaseNum> Mul<$t<N>> for $tv<N> { impl<N: BaseNum> Mul<$t<N>> for $tv<N> {
type Output = $tv<N>; type Output = $tv<N>;
#[inline] #[inline]
fn mul(self, right: $t<N>) -> $tv<N> { fn mul(self, right: $t<N>) -> $tv<N> {
self * right.isometry * right.scale (self * right.scale) * right.isometry
} }
} }
) )
@ -161,7 +213,7 @@ macro_rules! sim_transform_impl(
#[inline] #[inline]
fn inv_transform(&self, p: &$tp<N>) -> $tp<N> { fn inv_transform(&self, p: &$tp<N>) -> $tp<N> {
self.isometry.inv_transform(p) / self.scale self.isometry.inv_transform(&(*p / self.scale))
} }
} }
) )

View File

@ -2,30 +2,22 @@ extern crate nalgebra as na;
extern crate rand; extern crate rand;
use rand::random; use rand::random;
use na::{Pnt3, Vec3, Vec1, Rot2, Rot3, Persp3, PerspMat3, Ortho3, OrthoMat3, Iso2, Iso3, BaseFloat, use na::{Pnt2, Pnt3, Vec3, Vec1, Rot2, Rot3, Persp3, PerspMat3, Ortho3, OrthoMat3, Iso2, Iso3,
Sim2, Sim3}; Sim2, Sim3, BaseFloat, Transform};
macro_rules! test_transform_inv_transform_impl( macro_rules! test_transform_inv_transform_impl(
($t: ty, $p: ty) => ( ($t: ty, $p: ty) => (
for _ in 0usize .. 10000 { for _ in 0usize .. 10000 {
let randmat: $t = random(); let randmat: $t = random();
let randvec: $p = random(); let expected: $p = random();
let tvec = randmat.transform(&randvec); let computed = randmat.inv_transform(&randmat.transform(&expected));
let original = randmat.inv_transform(&randvec);
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] #[test]
fn test_rotation2() { fn test_rotation2() {
for _ in 0usize .. 10000 { for _ in 0usize .. 10000 {
@ -218,3 +210,33 @@ fn test_ortho() {
assert!(na::approx_eq(&pm.znear(), &24.0)); assert!(na::approx_eq(&pm.znear(), &24.0));
assert!(na::approx_eq(&pm.zfar(), &61.0)); assert!(na::approx_eq(&pm.zfar(), &61.0));
} }
#[test]
fn test_transform_inv_transform_rot2() {
test_transform_inv_transform_impl!(Rot2<f32>, Pnt2<f32>);
}
#[test]
fn test_transform_inv_transform_rot3() {
test_transform_inv_transform_impl!(Rot3<f32>, Pnt3<f32>);
}
#[test]
fn test_transform_inv_transform_iso2() {
test_transform_inv_transform_impl!(Iso2<f32>, Pnt2<f32>);
}
#[test]
fn test_transform_inv_transform_iso3() {
test_transform_inv_transform_impl!(Iso3<f32>, Pnt3<f32>);
}
#[test]
fn test_transform_inv_transform_sim2() {
test_transform_inv_transform_impl!(Sim2<f32>, Pnt2<f32>);
}
#[test]
fn test_transform_inv_transform_sim3() {
test_transform_inv_transform_impl!(Sim3<f32>, Pnt3<f32>);
}