use alga::general::{AbstractMagma, AbstractGroup, AbstractLoop, AbstractMonoid, AbstractQuasigroup, AbstractSemigroup, Real, Inverse, Multiplicative, Identity, Id}; use alga::linear::{Transformation, ProjectiveTransformation, Similarity, AffineTransformation, Isometry, DirectIsometry, Translation}; use core::ColumnVector; use core::dimension::{DimName, U1}; use core::storage::OwnedStorage; use core::allocator::OwnedAllocator; use geometry::{TranslationBase, PointBase}; /* * * Algebraic structures. * */ impl Identity for TranslationBase where N: Real, S: OwnedStorage, S::Alloc: OwnedAllocator { #[inline] fn identity() -> Self { Self::identity() } } impl Inverse for TranslationBase where N: Real, S: OwnedStorage, S::Alloc: OwnedAllocator { #[inline] fn inverse(&self) -> Self { self.inverse() } #[inline] fn inverse_mut(&mut self) { self.inverse_mut() } } impl AbstractMagma for TranslationBase where N: Real, S: OwnedStorage, 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 TranslationBase where N: Real, S: OwnedStorage, S::Alloc: OwnedAllocator { } )*} ); impl_multiplicative_structures!( AbstractSemigroup, AbstractMonoid, AbstractQuasigroup, AbstractLoop, AbstractGroup ); /* * * Transformation groups. * */ impl Transformation> for TranslationBase where N: Real, S: OwnedStorage, S::Alloc: OwnedAllocator { #[inline] fn transform_point(&self, pt: &PointBase) -> PointBase { pt + &self.vector } #[inline] fn transform_vector(&self, v: &ColumnVector) -> ColumnVector { v.clone() } } impl ProjectiveTransformation> for TranslationBase where N: Real, S: OwnedStorage, S::Alloc: OwnedAllocator { #[inline] fn inverse_transform_point(&self, pt: &PointBase) -> PointBase { pt - &self.vector } #[inline] fn inverse_transform_vector(&self, v: &ColumnVector) -> ColumnVector { v.clone() } } impl AffineTransformation> for TranslationBase where N: Real, S: OwnedStorage, S::Alloc: OwnedAllocator { type Rotation = Id; type NonUniformScaling = Id; type Translation = Self; #[inline] fn decompose(&self) -> (Self, Id, Id, Id) { (self.clone(), Id::new(), Id::new(), Id::new()) } #[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, _: &Self::Rotation) -> Self { self.clone() } #[inline] fn prepend_rotation(&self, _: &Self::Rotation) -> Self { self.clone() } #[inline] fn append_scaling(&self, _: &Self::NonUniformScaling) -> Self { self.clone() } #[inline] fn prepend_scaling(&self, _: &Self::NonUniformScaling) -> Self { self.clone() } } impl Similarity> for TranslationBase where N: Real, S: OwnedStorage, S::Alloc: OwnedAllocator { type Scaling = Id; #[inline] fn translation(&self) -> Self { self.clone() } #[inline] fn rotation(&self) -> Id { Id::new() } #[inline] fn scaling(&self) -> Id { Id::new() } } macro_rules! marker_impl( ($($Trait: ident),*) => {$( impl $Trait> for TranslationBase where N: Real, S: OwnedStorage, S::Alloc: OwnedAllocator { } )*} ); marker_impl!(Isometry, DirectIsometry); /// Subgroups of the n-dimensional translation group `T(n)`. impl Translation> for TranslationBase where N: Real, S: OwnedStorage, S::Alloc: OwnedAllocator { #[inline] fn to_vector(&self) -> ColumnVector { self.vector.clone() } #[inline] fn from_vector(v: ColumnVector) -> Option { Some(Self::from_vector(v)) } #[inline] fn powf(&self, n: N) -> Option { Some(Self::from_vector(&self.vector * n)) } #[inline] fn translation_between(a: &PointBase, b: &PointBase) -> Option { Some(Self::from_vector(b - a)) } }