#![macro_use] macro_rules! submat_impl( ($t: ident, $submatrix: ident) => ( impl $t { /// This rotation's underlying matrix. #[inline] pub fn submatrix(&self) -> &$submatrix { &self.submatrix } } ) ); macro_rules! rotate_impl( ($t: ident, $tv: ident, $tp: ident) => ( impl Rotate<$tv> for $t { #[inline] fn rotate(&self, v: &$tv) -> $tv { *self * *v } #[inline] fn inverse_rotate(&self, v: &$tv) -> $tv { *v * *self } } impl Rotate<$tp> for $t { #[inline] fn rotate(&self, p: &$tp) -> $tp { *self * *p } #[inline] fn inverse_rotate(&self, p: &$tp) -> $tp { *p * *self } } ) ); macro_rules! transform_impl( ($t: ident, $tv: ident, $tp: ident) => ( impl Transform<$tv> for $t { #[inline] fn transform(&self, v: &$tv) -> $tv { self.rotate(v) } #[inline] fn inverse_transform(&self, v: &$tv) -> $tv { self.inverse_rotate(v) } } impl Transform<$tp> for $t { #[inline] fn transform(&self, p: &$tp) -> $tp { self.rotate(p) } #[inline] fn inverse_transform(&self, p: &$tp) -> $tp { self.inverse_rotate(p) } } ) ); macro_rules! dim_impl( ($t: ident, $dimension: expr) => ( impl Dimension for $t { #[inline] fn dimension(_: Option<$t>) -> usize { $dimension } } ) ); macro_rules! rotation_matrix_impl( ($t: ident, $tlv: ident, $tav: ident) => ( impl + BaseFloat> RotationMatrix, $tav> for $t { type Output = $t; #[inline] fn to_rotation_matrix(&self) -> $t { self.clone() } } ) ); macro_rules! one_impl( ($t: ident) => ( impl One for $t { #[inline] fn one() -> $t { $t { submatrix: ::one() } } } ) ); macro_rules! eye_impl( ($t: ident) => ( 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() } } } ) ); macro_rules! diag_impl( ($t: ident, $tv: ident) => ( impl Diagonal<$tv> for $t { #[inline] fn from_diagonal(diagonal: &$tv) -> $t { $t { submatrix: Diagonal::from_diagonal(diagonal) } } #[inline] fn diagonal(&self) -> $tv { self.submatrix.diagonal() } } ) ); macro_rules! rotation_mul_rotation_impl( ($t: ident) => ( 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 } } ) ); macro_rules! rotation_mul_vec_impl( ($t: ident, $tv: ident) => ( impl Mul<$tv> for $t { type Output = $tv; #[inline] fn mul(self, right: $tv) -> $tv { self.submatrix * right } } ) ); macro_rules! rotation_mul_point_impl( ($t: ident, $tv: ident) => ( rotation_mul_vec_impl!($t, $tv); ) ); macro_rules! vec_mul_rotation_impl( ($t: ident, $tv: ident) => ( impl Mul<$t> for $tv { type Output = $tv; #[inline] fn mul(self, right: $t) -> $tv { self * right.submatrix } } impl MulAssign<$t> for $tv { #[inline] fn mul_assign(&mut self, right: $t) { *self *= right.submatrix } } ) ); macro_rules! point_mul_rotation_impl( ($t: ident, $tv: ident) => ( vec_mul_rotation_impl!($t, $tv); ) ); macro_rules! inverse_impl( ($t: ident) => ( 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()) } } ) ); macro_rules! transpose_impl( ($t: ident) => ( 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() } } ) ); macro_rules! row_impl( ($t: ident, $tv: ident) => ( impl Row<$tv> for $t { #[inline] fn nrows(&self) -> usize { self.submatrix.nrows() } #[inline] fn row(&self, i: usize) -> $tv { self.submatrix.row(i) } #[inline] fn set_row(&mut self, i: usize, row: $tv) { self.submatrix.set_row(i, row); } } ) ); macro_rules! column_impl( ($t: ident, $tv: ident) => ( impl Column<$tv> for $t { #[inline] fn ncols(&self) -> usize { self.submatrix.ncols() } #[inline] fn column(&self, i: usize) -> $tv { self.submatrix.column(i) } #[inline] fn set_column(&mut self, i: usize, column: $tv) { self.submatrix.set_column(i, column); } } ) ); macro_rules! index_impl( ($t: ident) => ( impl Index<(usize, usize)> for $t { type Output = N; fn index(&self, i: (usize, usize)) -> &N { &self.submatrix[i] } } ) ); macro_rules! to_homogeneous_impl( ($t: ident, $tm: ident) => ( impl ToHomogeneous<$tm> for $t { #[inline] fn to_homogeneous(&self) -> $tm { self.submatrix.to_homogeneous() } } ) ); macro_rules! approx_eq_impl( ($t: ident) => ( 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) } } ) ); macro_rules! absolute_impl( ($t: ident, $tm: ident) => ( impl> Absolute<$tm> for $t { #[inline] fn abs(m: &$t) -> $tm { Absolute::abs(&m.submatrix) } } ) ); macro_rules! rotation_display_impl( ($t: ident) => ( 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, "}}") } } ) );