use core::num::{One, Zero}; 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}; pub struct Transform { submat : M, subtrans : V } pub fn transform(mat: &M, trans: &V) -> Transform { Transform { submat: *mat, subtrans: *trans } } impl Dim for Transform { fn dim() -> uint { Dim::dim::() } } impl One for Transform { fn one() -> Transform { Transform { submat: One::one(), subtrans: Zero::zero() } } } impl Zero for Transform { fn zero() -> Transform { Transform { submat: Zero::zero(), subtrans: Zero::zero() } } fn is_zero(&self) -> bool { self.submat.is_zero() && self.subtrans.is_zero() } } impl + Mul, V:Copy + Add> Mul, Transform> for Transform { fn mul(&self, other: &Transform) -> Transform { Transform { submat: self.submat * other.submat, subtrans: self.subtrans + self.submat.rmul(&other.subtrans) } } } impl, V> RMul for Transform { fn rmul(&self, other: &V) -> V { self.submat.rmul(other) } } impl, V> LMul for Transform { fn lmul(&self, other: &V) -> V { 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 { fn invert(&mut self) { self.submat.invert(); self.subtrans = self.submat.rmul(&-self.subtrans); } fn inverse(&self) -> Transform { let mut res = *self; res.invert(); res } } impl, V:FuzzyEq> FuzzyEq for Transform { fn fuzzy_eq(&self, other: &Transform) -> bool { self.submat.fuzzy_eq(&other.submat) && self.subtrans.fuzzy_eq(&other.subtrans) } fn fuzzy_eq_eps(&self, other: &Transform, epsilon: &T) -> bool { self.submat.fuzzy_eq_eps(&other.submat, epsilon) && self.subtrans.fuzzy_eq_eps(&other.subtrans, epsilon) } } impl Rand for Transform { fn rand(rng: &R) -> Transform { transform(&rng.gen(), &rng.gen()) } } impl ToStr for Transform { fn to_str(&self) -> ~str { ~"Transform {" + " submat: " + self.submat.to_str() + " subtrans: " + self.subtrans.to_str() + " }" } }