From dc0757b2e56e9fe2e7b3e769957c0667ba9fa4e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Crozet?= Date: Sun, 19 May 2013 11:44:27 +0000 Subject: [PATCH] Add rotation and translation traits. --- Makefile | 1 + src/adaptors/rotmat.rs | 45 ++++++++++++++++++++----- src/adaptors/transform.rs | 26 ++++++++++++++ src/dim1/vec1.rs | 17 ++++++++-- src/dim2/vec2.rs | 25 ++++++++++---- src/dim3/vec3.rs | 18 ++++++++-- src/nalgebra.rc | 2 ++ src/ndim/nvec.rs | 15 ++++++++- src/traits/rotation.rs | 6 ++++ src/traits/translation.rs | 6 ++++ src/traits/workarounds/trigonometric.rs | 10 ++++-- 11 files changed, 149 insertions(+), 22 deletions(-) create mode 100644 src/traits/rotation.rs create mode 100644 src/traits/translation.rs diff --git a/Makefile b/Makefile index d616d6ee..c628ff3a 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,7 @@ all: test: rust test src/nalgebra.rc + rm nalgebratest~ doc: rust test src/nalgebra.rc diff --git a/src/adaptors/rotmat.rs b/src/adaptors/rotmat.rs index d1967487..f0dcb42b 100644 --- a/src/adaptors/rotmat.rs +++ b/src/adaptors/rotmat.rs @@ -6,6 +6,8 @@ use traits::workarounds::trigonometric::Trigonometric; use traits::dim::Dim; use traits::inv::Inv; use traits::transpose::Transpose; +use traits::rotation::Rotation; +use dim1::vec1::{Vec1, vec1}; use dim2::mat2::{Mat2, mat2}; use dim3::mat3::{Mat3, mat3}; use dim3::vec3::{Vec3}; @@ -57,13 +59,40 @@ pub fn rotmat3 + One + Sub + Add + } } -impl> Rand for Rotmat> +impl + Trigonometric + Neg + Mul + Add + Copy> +Rotation> for Rotmat> +{ + fn rotation(&self) -> Vec1 + { vec1(-Trigonometric::atan(self.submat.m12 / self.submat.m11)) } + + fn rotated(&self, rot: &Vec1) -> Rotmat> + { rotmat2(rot.x) * *self } + + fn rotate(&mut self, rot: &Vec1) + { *self = self.rotated(rot) } +} + +impl + Trigonometric + Neg + Mul + Add + Copy + + One + Sub> +Rotation<(Vec3, T)> for Rotmat> +{ + fn rotation(&self) -> (Vec3, T) + { fail!("Not yet implemented.") } + + fn rotated(&self, &(axis, angle): &(Vec3, T)) -> Rotmat> + { rotmat3(&axis, angle) * *self } + + fn rotate(&mut self, rot: &(Vec3, T)) + { *self = self.rotated(rot) } +} + +impl> Rand for Rotmat> { fn rand(rng: &R) -> Rotmat> { rotmat2(rng.gen()) } } -impl + One + Sub + Add + +impl + One + Sub + Add + Mul> Rand for Rotmat> { @@ -77,13 +106,13 @@ impl Dim for Rotmat { Dim::dim::() } } -impl One for Rotmat +impl One for Rotmat { fn one() -> Rotmat { Rotmat { submat: One::one() } } } -impl> Mul, Rotmat> for Rotmat +impl> Mul, Rotmat> for Rotmat { fn mul(&self, other: &Rotmat) -> Rotmat { Rotmat { submat: self.submat.mul(&other.submat) } } @@ -101,7 +130,7 @@ impl> LMul for Rotmat { self.submat.lmul(other) } } -impl +impl Inv for Rotmat { fn invert(&mut self) @@ -111,7 +140,7 @@ Inv for Rotmat { self.transposed() } } -impl +impl Transpose for Rotmat { fn transposed(&self) -> Rotmat @@ -121,7 +150,7 @@ Transpose for Rotmat { self.submat.transpose() } } -impl> FuzzyEq for Rotmat +impl> FuzzyEq for Rotmat { fn fuzzy_eq(&self, other: &Rotmat) -> bool { self.submat.fuzzy_eq(&other.submat) } @@ -130,7 +159,7 @@ impl> FuzzyEq for Rotmat { self.submat.fuzzy_eq_eps(&other.submat, epsilon) } } -impl ToStr for Rotmat +impl ToStr for Rotmat { fn to_str(&self) -> ~str { ~"Rotmat {" + " submat: " + self.submat.to_str() + " }" } diff --git a/src/adaptors/transform.rs b/src/adaptors/transform.rs index 60b2c278..e8fcab6e 100644 --- a/src/adaptors/transform.rs +++ b/src/adaptors/transform.rs @@ -3,6 +3,8 @@ use core::rand::{Rand, Rng, RngUtil}; use std::cmp::FuzzyEq; use traits::dim::Dim; use traits::inv::Inv; +use traits::rotation::Rotation; +use traits::translation::Translation; use traits::transpose::Transpose; use traits::workarounds::rlmul::{RMul, LMul}; @@ -58,6 +60,30 @@ impl, V> LMul for Transform { self.submat.lmul(other) } } +impl> Translation for Transform +{ + fn translation(&self) -> V + { self.subtrans.translation() } + + fn translated(&self, t: &V) -> Transform + { transform(&self.submat, &self.subtrans.translated(t)) } + + fn translate(&mut self, t: &V) + { self.subtrans.translate(t) } +} + +impl + Copy, V: Copy> Rotation for Transform +{ + fn rotation(&self) -> V + { self.submat.rotation() } + + fn rotated(&self, rot: &V) -> Transform + { transform(&self.submat.rotated(rot), &self.subtrans) } + + fn rotate(&mut self, rot: &V) + { self.submat.rotate(rot) } +} + impl, V:Copy + Neg> Inv for Transform { diff --git a/src/dim1/vec1.rs b/src/dim1/vec1.rs index 05c0c151..b081c0bb 100644 --- a/src/dim1/vec1.rs +++ b/src/dim1/vec1.rs @@ -1,10 +1,11 @@ use core::num::{Zero, One, Algebraic}; use core::rand::{Rand, Rng, RngUtil}; use std::cmp::FuzzyEq; -use traits::dot::Dot; -use traits::dim::Dim; use traits::basis::Basis; +use traits::dim::Dim; +use traits::dot::Dot; use traits::norm::Norm; +use traits::translation::Translation; use traits::workarounds::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub}; #[deriving(Eq)] @@ -73,6 +74,18 @@ ScalarSub for Vec1 { self.x -= *s; } } +impl> Translation> for Vec1 +{ + fn translation(&self) -> Vec1 + { *self } + + fn translated(&self, t: &Vec1) -> Vec1 + { self + *t } + + fn translate(&mut self, t: &Vec1) + { *self += *t } +} + impl + Add + Algebraic> Dot for Vec1 { fn dot(&self, other : &Vec1) -> T diff --git a/src/dim2/vec2.rs b/src/dim2/vec2.rs index 2b40e694..8798584e 100644 --- a/src/dim2/vec2.rs +++ b/src/dim2/vec2.rs @@ -1,12 +1,13 @@ use core::num::{Zero, One, Algebraic}; use core::rand::{Rand, Rng, RngUtil}; -use std::cmp::FuzzyEq; -use traits::dot::Dot; -use traits::dim::Dim; -use traits::cross::Cross; -use traits::basis::Basis; -use traits::norm::Norm; use dim1::vec1::{Vec1, vec1}; +use std::cmp::FuzzyEq; +use traits::basis::Basis; +use traits::cross::Cross; +use traits::dim::Dim; +use traits::dot::Dot; +use traits::norm::Norm; +use traits::translation::Translation; use traits::workarounds::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub}; #[deriving(Eq)] @@ -90,6 +91,18 @@ ScalarSub for Vec2 } } +impl> Translation> for Vec2 +{ + fn translation(&self) -> Vec2 + { *self } + + fn translated(&self, t: &Vec2) -> Vec2 + { self + *t } + + fn translate(&mut self, t: &Vec2) + { *self += *t; } +} + impl + Add + Algebraic> Dot for Vec2 { fn dot(&self, other : &Vec2) -> T diff --git a/src/dim3/vec3.rs b/src/dim3/vec3.rs index b2b14028..074c3781 100644 --- a/src/dim3/vec3.rs +++ b/src/dim3/vec3.rs @@ -1,11 +1,12 @@ use core::num::{Zero, One, Algebraic, abs}; use core::rand::{Rand, Rng, RngUtil}; use std::cmp::FuzzyEq; +use traits::basis::Basis; +use traits::cross::Cross; use traits::dim::Dim; use traits::dot::Dot; -use traits::cross::Cross; -use traits::basis::Basis; use traits::norm::Norm; +use traits::translation::Translation; use traits::workarounds::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub}; #[deriving(Eq)] @@ -94,6 +95,19 @@ ScalarSub for Vec3 } } +impl> Translation> for Vec3 +{ + fn translation(&self) -> Vec3 + { *self } + + fn translated(&self, t: &Vec3) -> Vec3 + { self + *t } + + fn translate(&mut self, t: &Vec3) + { *self += *t; } +} + + impl> Neg> for Vec3 { diff --git a/src/nalgebra.rc b/src/nalgebra.rc index bccf2890..6e5ec61a 100644 --- a/src/nalgebra.rc +++ b/src/nalgebra.rc @@ -46,6 +46,8 @@ mod traits mod dim; mod basis; mod norm; + mod rotation; + mod translation; mod workarounds { diff --git a/src/ndim/nvec.rs b/src/ndim/nvec.rs index a226abef..536cf8e8 100644 --- a/src/ndim/nvec.rs +++ b/src/ndim/nvec.rs @@ -2,10 +2,11 @@ use core::num::{Zero, One, Algebraic}; use core::rand::{Rand, Rng, RngUtil}; use core::vec::{map_zip, from_elem, map, all, all2}; use std::cmp::FuzzyEq; +use traits::basis::Basis; use traits::dim::Dim; use traits::dot::Dot; use traits::norm::Norm; -use traits::basis::Basis; +use traits::translation::Translation; use traits::workarounds::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub}; // D is a phantom parameter, used only as a dimensional token. @@ -118,6 +119,18 @@ ScalarSub for NVec } } +impl> Translation> for NVec +{ + fn translation(&self) -> NVec + { self.clone() } + + fn translated(&self, t: &NVec) -> NVec + { self + *t } + + fn translate(&mut self, t: &NVec) + { *self = *self + *t; } +} + impl + Add + Quot + Algebraic + Zero + Clone> Norm for NVec diff --git a/src/traits/rotation.rs b/src/traits/rotation.rs new file mode 100644 index 00000000..7a0307d3 --- /dev/null +++ b/src/traits/rotation.rs @@ -0,0 +1,6 @@ +pub trait Rotation +{ + fn rotation(&self) -> V; + fn rotated(&self, &V) -> Self; + fn rotate(&mut self, &V); +} diff --git a/src/traits/translation.rs b/src/traits/translation.rs new file mode 100644 index 00000000..1e1e58ae --- /dev/null +++ b/src/traits/translation.rs @@ -0,0 +1,6 @@ +pub trait Translation +{ + fn translation(&self) -> V; + fn translated(&self, &V) -> Self; + fn translate(&mut self, &V); +} diff --git a/src/traits/workarounds/trigonometric.rs b/src/traits/workarounds/trigonometric.rs index 7902a052..9f28abd8 100644 --- a/src/traits/workarounds/trigonometric.rs +++ b/src/traits/workarounds/trigonometric.rs @@ -1,12 +1,13 @@ // Trigonometric is available in core, but compilation fails with internal // error. -use core::f64::{cos, sin}; +use core::f64::{cos, sin, atan}; pub trait Trigonometric { - fn cos(Self) -> Self; - fn sin(Self) -> Self; + fn cos(Self) -> Self; + fn sin(Self) -> Self; + fn atan(Self) -> Self; } impl Trigonometric for f64 @@ -16,4 +17,7 @@ impl Trigonometric for f64 fn sin(a: f64) -> f64 { sin(a) } + + fn atan(a: f64) -> f64 + { atan(a) } }