use alga::general::{ AbstractGroup, AbstractLoop, AbstractMagma, AbstractMonoid, AbstractQuasigroup, AbstractSemigroup, Id, Identity, TwoSidedInverse, Multiplicative, Real, }; use alga::linear::{ self, AffineTransformation, DirectIsometry, Isometry, OrthogonalTransformation, ProjectiveTransformation, Similarity, Transformation, }; use crate::base::allocator::Allocator; use crate::base::dimension::DimName; use crate::base::{DefaultAllocator, VectorN}; use crate::geometry::{Point, Rotation}; /* * * Algebraic structures. * */ impl Identity for Rotation where DefaultAllocator: Allocator { #[inline] fn identity() -> Self { Self::identity() } } impl TwoSidedInverse for Rotation where DefaultAllocator: Allocator { #[inline] fn two_sided_inverse(&self) -> Self { self.transpose() } #[inline] fn two_sided_inverse_mut(&mut self) { self.transpose_mut() } } impl AbstractMagma for Rotation where DefaultAllocator: Allocator { #[inline] fn operate(&self, rhs: &Self) -> Self { self * rhs } } macro_rules! impl_multiplicative_structures( ($($marker: ident<$operator: ident>),* $(,)*) => {$( impl $marker<$operator> for Rotation where DefaultAllocator: Allocator { } )*} ); impl_multiplicative_structures!( AbstractSemigroup, AbstractMonoid, AbstractQuasigroup, AbstractLoop, AbstractGroup ); /* * * Transformation groups. * */ impl Transformation> for Rotation where DefaultAllocator: Allocator + Allocator { #[inline] fn transform_point(&self, pt: &Point) -> Point { self * pt } #[inline] fn transform_vector(&self, v: &VectorN) -> VectorN { self * v } } impl ProjectiveTransformation> for Rotation where DefaultAllocator: Allocator + Allocator { #[inline] fn inverse_transform_point(&self, pt: &Point) -> Point { Point::from(self.inverse_transform_vector(&pt.coords)) } #[inline] fn inverse_transform_vector(&self, v: &VectorN) -> VectorN { self.matrix().tr_mul(v) } } impl AffineTransformation> for Rotation where DefaultAllocator: Allocator + Allocator { type Rotation = Self; type NonUniformScaling = Id; type Translation = Id; #[inline] fn decompose(&self) -> (Id, Self, Id, Self) { (Id::new(), self.clone(), Id::new(), Self::identity()) } #[inline] fn append_translation(&self, _: &Self::Translation) -> Self { self.clone() } #[inline] fn prepend_translation(&self, _: &Self::Translation) -> Self { self.clone() } #[inline] fn append_rotation(&self, r: &Self::Rotation) -> Self { r * self } #[inline] fn prepend_rotation(&self, r: &Self::Rotation) -> Self { self * r } #[inline] fn append_scaling(&self, _: &Self::NonUniformScaling) -> Self { self.clone() } #[inline] fn prepend_scaling(&self, _: &Self::NonUniformScaling) -> Self { self.clone() } } impl Similarity> for Rotation where DefaultAllocator: Allocator + Allocator { type Scaling = Id; #[inline] fn translation(&self) -> Id { Id::new() } #[inline] fn rotation(&self) -> Self { self.clone() } #[inline] fn scaling(&self) -> Id { Id::new() } } macro_rules! marker_impl( ($($Trait: ident),*) => {$( impl $Trait> for Rotation where DefaultAllocator: Allocator + Allocator { } )*} ); marker_impl!(Isometry, DirectIsometry, OrthogonalTransformation); /// Subgroups of the n-dimensional rotation group `SO(n)`. impl linear::Rotation> for Rotation where DefaultAllocator: Allocator + Allocator { #[inline] fn powf(&self, _: N) -> Option { // XXX: Add the general case. // XXX: Use specialization for 2D and 3D. unimplemented!() } #[inline] fn rotation_between(_: &VectorN, _: &VectorN) -> Option { // XXX: Add the general case. // XXX: Use specialization for 2D and 3D. unimplemented!() } #[inline] fn scaled_rotation_between(_: &VectorN, _: &VectorN, _: N) -> Option { // XXX: Add the general case. // XXX: Use specialization for 2D and 3D. unimplemented!() } } /* impl Matrix for Rotation { type Field = N; type Row = Matrix; type Column = Matrix; type Transpose = Self; #[inline] fn nrows(&self) -> usize { self.submatrix.nrows() } #[inline] fn ncolumns(&self) -> usize { self.submatrix.ncolumns() } #[inline] fn row(&self, i: usize) -> Self::Row { self.submatrix.row(i) } #[inline] fn column(&self, i: usize) -> Self::Column { self.submatrix.column(i) } #[inline] fn get(&self, i: usize, j: usize) -> Self::Field { self.submatrix[(i, j)] } #[inline] unsafe fn get_unchecked(&self, i: usize, j: usize) -> Self::Field { self.submatrix.at_fast(i, j) } #[inline] fn transpose(&self) -> Self::Transpose { Rotation::from_matrix_unchecked(self.submatrix.transpose()) } } impl SquareMatrix for Rotation { type Vector = Matrix; #[inline] fn diagonal(&self) -> Self::Coordinates { self.submatrix.diagonal() } #[inline] fn determinant(&self) -> Self::Field { crate::one() } #[inline] fn try_inverse(&self) -> Option { Some(::transpose(self)) } #[inline] fn try_inverse_mut(&mut self) -> bool { self.transpose_mut(); true } #[inline] fn transpose_mut(&mut self) { self.submatrix.transpose_mut() } } impl InversibleSquareMatrix for Rotation { } */