use alga::general::{AbstractMagma, AbstractGroup, AbstractLoop, AbstractMonoid, AbstractQuasigroup, AbstractSemigroup, Real, Inverse, Multiplicative, Identity}; use alga::linear::{Transformation, AffineTransformation, Rotation, Similarity, ProjectiveTransformation}; use core::ColumnVector; use core::dimension::{DimName, U1}; use core::storage::OwnedStorage; use core::allocator::OwnedAllocator; use geometry::{SimilarityBase, TranslationBase, PointBase}; /* * * Algebraic structures. * */ impl Identity for SimilarityBase where N: Real, S: OwnedStorage, R: Rotation>, S::Alloc: OwnedAllocator { #[inline] fn identity() -> Self { Self::identity() } } impl Inverse for SimilarityBase where N: Real, S: OwnedStorage, R: Rotation>, S::Alloc: OwnedAllocator { #[inline] fn inverse(&self) -> Self { self.inverse() } #[inline] fn inverse_mut(&mut self) { self.inverse_mut() } } impl AbstractMagma for SimilarityBase where N: Real, S: OwnedStorage, R: Rotation>, S::Alloc: OwnedAllocator { #[inline] fn operate(&self, rhs: &Self) -> Self { self * rhs } } macro_rules! impl_multiplicative_structures( ($($marker: ident<$operator: ident>),* $(,)*) => {$( impl $marker<$operator> for SimilarityBase where N: Real, S: OwnedStorage, R: Rotation>, S::Alloc: OwnedAllocator { } )*} ); impl_multiplicative_structures!( AbstractSemigroup, AbstractMonoid, AbstractQuasigroup, AbstractLoop, AbstractGroup ); /* * * Transformation groups. * */ impl Transformation> for SimilarityBase where N: Real, S: OwnedStorage, R: Rotation>, S::Alloc: OwnedAllocator { #[inline] fn transform_point(&self, pt: &PointBase) -> PointBase { self * pt } #[inline] fn transform_vector(&self, v: &ColumnVector) -> ColumnVector { self * v } } impl ProjectiveTransformation> for SimilarityBase where N: Real, S: OwnedStorage, R: Rotation>, S::Alloc: OwnedAllocator { #[inline] fn inverse_transform_point(&self, pt: &PointBase) -> PointBase { self.isometry.inverse_transform_point(pt) / self.scaling() } #[inline] fn inverse_transform_vector(&self, v: &ColumnVector) -> ColumnVector { self.isometry.inverse_transform_vector(v) / self.scaling() } } impl AffineTransformation> for SimilarityBase where N: Real, S: OwnedStorage, R: Rotation>, S::Alloc: OwnedAllocator { type NonUniformScaling = N; type Rotation = R; type Translation = TranslationBase; #[inline] fn decompose(&self) -> (TranslationBase, R, N, R) { (self.isometry.translation.clone(), self.isometry.rotation.clone(), self.scaling(), R::identity()) } #[inline] fn append_translation(&self, t: &Self::Translation) -> Self { t * self } #[inline] fn prepend_translation(&self, t: &Self::Translation) -> Self { self * t } #[inline] fn append_rotation(&self, r: &Self::Rotation) -> Self { SimilarityBase::from_isometry(self.isometry.append_rotation(r), self.scaling()) } #[inline] fn prepend_rotation(&self, r: &Self::Rotation) -> Self { self * r } #[inline] fn append_scaling(&self, s: &Self::NonUniformScaling) -> Self { self.append_scaling(*s) } #[inline] fn prepend_scaling(&self, s: &Self::NonUniformScaling) -> Self { self.prepend_scaling(*s) } #[inline] fn append_rotation_wrt_point(&self, r: &Self::Rotation, p: &PointBase) -> Option { let mut res = self.clone(); res.append_rotation_wrt_point_mut(r, p); Some(res) } } impl Similarity> for SimilarityBase where N: Real, S: OwnedStorage, R: Rotation>, S::Alloc: OwnedAllocator { type Scaling = N; #[inline] fn translation(&self) -> TranslationBase { self.isometry.translation() } #[inline] fn rotation(&self) -> R { self.isometry.rotation() } #[inline] fn scaling(&self) -> N { self.scaling() } }