#![macro_use] macro_rules! rotation_impl( ($t: ident, $submatrix: ident, $vector: ident, $rotvector: ident, $point: ident, $homogeneous: ident) => ( special_orthogonal_group_impl!($t, $point, $vector); impl $t { /// This rotation's underlying matrix. #[inline] pub fn submatrix(&self) -> &$submatrix { &self.submatrix } } /* * * Rotate Vector and Point * */ impl Rotate<$vector> for $t { #[inline] fn rotate(&self, v: &$vector) -> $vector { *self * *v } #[inline] fn inverse_rotate(&self, v: &$vector) -> $vector { *v * *self } } impl Rotate<$point> for $t { #[inline] fn rotate(&self, p: &$point) -> $point { *self * *p } #[inline] fn inverse_rotate(&self, p: &$point) -> $point { *p * *self } } /* * * Transform Vector and Point * */ impl Transform<$vector> for $t { #[inline] fn transform(&self, v: &$vector) -> $vector { self.rotate(v) } #[inline] fn inverse_transform(&self, v: &$vector) -> $vector { self.inverse_rotate(v) } } impl Transform<$point> for $t { #[inline] fn transform(&self, p: &$point) -> $point { self.rotate(p) } #[inline] fn inverse_transform(&self, p: &$point) -> $point { self.inverse_rotate(p) } } /* * * Rotation Matrix * */ impl + BaseFloat> RotationMatrix, $rotvector> for $t { type Output = $t; #[inline] fn to_rotation_matrix(&self) -> $t { self.clone() } } /* * * One * */ impl One for $t { #[inline] fn one() -> $t { $t { submatrix: ::one() } } } /* * * Eye * */ impl Eye for $t { #[inline] fn new_identity(dimension: usize) -> $t { if dimension != ::dimension::<$t>() { panic!("Dimension mismatch: should be {}, got {}.", ::dimension::<$t>(), dimension); } else { ::one() } } } /* * * Diagonal * */ impl Diagonal<$vector> for $t { #[inline] fn from_diagonal(diagonal: &$vector) -> $t { $t { submatrix: Diagonal::from_diagonal(diagonal) } } #[inline] fn diagonal(&self) -> $vector { self.submatrix.diagonal() } } /* * * Rotation * Rotation * */ impl Mul<$t> for $t { type Output = $t; #[inline] fn mul(self, right: $t) -> $t { $t { submatrix: self.submatrix * right.submatrix } } } impl MulAssign<$t> for $t { #[inline] fn mul_assign(&mut self, right: $t) { self.submatrix *= right.submatrix } } /* * * Rotation * Vector * */ impl Mul<$vector> for $t { type Output = $vector; #[inline] fn mul(self, right: $vector) -> $vector { self.submatrix * right } } impl Mul<$t> for $vector { type Output = $vector; #[inline] fn mul(self, right: $t) -> $vector { self * right.submatrix } } impl MulAssign<$t> for $vector { #[inline] fn mul_assign(&mut self, right: $t) { *self *= right.submatrix } } /* * * Rotation * Point * */ impl Mul<$point> for $t { type Output = $point; #[inline] fn mul(self, right: $point) -> $point { self.submatrix * right } } impl Mul<$t> for $point { type Output = $point; #[inline] fn mul(self, right: $t) -> $point { self * right.submatrix } } impl MulAssign<$t> for $point { #[inline] fn mul_assign(&mut self, right: $t) { *self *= right.submatrix } } /* * * Inverse * */ impl Inverse for $t { #[inline] fn inverse_mut(&mut self) -> bool { self.transpose_mut(); // always succeed true } #[inline] fn inverse(&self) -> Option<$t> { // always succeed Some(self.transpose()) } } /* * * Transpose * */ impl Transpose for $t { #[inline] fn transpose(&self) -> $t { $t { submatrix: Transpose::transpose(&self.submatrix) } } #[inline] fn transpose_mut(&mut self) { self.submatrix.transpose_mut() } } /* * * Row * */ impl Row<$vector> for $t { #[inline] fn nrows(&self) -> usize { self.submatrix.nrows() } #[inline] fn row(&self, i: usize) -> $vector { self.submatrix.row(i) } #[inline] fn set_row(&mut self, i: usize, row: $vector) { self.submatrix.set_row(i, row); } } /* * * Column * */ impl Column<$vector> for $t { #[inline] fn ncols(&self) -> usize { self.submatrix.ncols() } #[inline] fn column(&self, i: usize) -> $vector { self.submatrix.column(i) } #[inline] fn set_column(&mut self, i: usize, column: $vector) { self.submatrix.set_column(i, column); } } /* * * Index * */ impl Index<(usize, usize)> for $t { type Output = N; fn index(&self, i: (usize, usize)) -> &N { &self.submatrix[i] } } /* * * ToHomogeneous * */ impl ToHomogeneous<$homogeneous> for $t { #[inline] fn to_homogeneous(&self) -> $homogeneous { self.submatrix.to_homogeneous() } } /* * * ApproxEq * */ impl> ApproxEq for $t { #[inline] fn approx_epsilon(_: Option<$t>) -> N { ApproxEq::approx_epsilon(None::) } #[inline] fn approx_ulps(_: Option<$t>) -> u32 { ApproxEq::approx_ulps(None::) } #[inline] fn approx_eq(&self, other: &$t) -> bool { ApproxEq::approx_eq(&self.submatrix, &other.submatrix) } #[inline] fn approx_eq_eps(&self, other: &$t, epsilon: &N) -> bool { ApproxEq::approx_eq_eps(&self.submatrix, &other.submatrix, epsilon) } #[inline] fn approx_eq_ulps(&self, other: &$t, ulps: u32) -> bool { ApproxEq::approx_eq_ulps(&self.submatrix, &other.submatrix, ulps) } } /* * * Absolute * */ impl> Absolute<$submatrix> for $t { #[inline] fn abs(m: &$t) -> $submatrix { Absolute::abs(&m.submatrix) } } /* * * Display * */ impl fmt::Display for $t { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let precision = f.precision().unwrap_or(3); try!(writeln!(f, "Rotation matrix {{")); try!(write!(f, "{:.*}", precision, self.submatrix)); writeln!(f, "}}") } } /* * * Arbitrary * */ #[cfg(feature="arbitrary")] impl Arbitrary for $t { fn arbitrary(g: &mut G) -> $t { $t::new(Arbitrary::arbitrary(g)) } } ) ); macro_rules! dim_impl( ($t: ident, $dimension: expr) => ( impl Dimension for $t { #[inline] fn dimension(_: Option<$t>) -> usize { $dimension } } ) );