use alga::general::{AbstractMagma, AbstractGroup, AbstractLoop, AbstractMonoid, AbstractQuasigroup, AbstractSemigroup, Real, Inverse, Multiplicative, Identity, Id}; use alga::linear::{Transformation, AffineTransformation, Similarity, Isometry, DirectIsometry, OrthogonalTransformation, Rotation, ProjectiveTransformation}; use core::ColumnVector; use core::storage::OwnedStorage; use core::allocator::OwnedAllocator; use core::dimension::{U1, U2}; use geometry::{PointBase, UnitComplex}; /* * * Implementations for UnitComplex. * */ impl Identity for UnitComplex { #[inline] fn identity() -> Self { Self::identity() } } impl AbstractMagma for UnitComplex { #[inline] fn operate(&self, rhs: &Self) -> Self { self * rhs } } impl Inverse for UnitComplex { #[inline] fn inverse(&self) -> Self { self.inverse() } #[inline] fn inverse_mut(&mut self) { self.inverse_mut() } } macro_rules! impl_structures( ($($marker: ident<$operator: ident>),* $(,)*) => {$( impl $marker<$operator> for UnitComplex { } )*} ); impl_structures!( AbstractSemigroup, AbstractQuasigroup, AbstractMonoid, AbstractLoop, AbstractGroup ); impl Transformation> for UnitComplex where N: Real, S: OwnedStorage, 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 UnitComplex where N: Real, S: OwnedStorage, S::Alloc: OwnedAllocator { #[inline] fn inverse_transform_point(&self, pt: &PointBase) -> PointBase { // FIXME: would it be useful performancewise not to call inverse explicitly (i-e. implement // the inverse transformation explicitly here) ? self.inverse() * pt } #[inline] fn inverse_transform_vector(&self, v: &ColumnVector) -> ColumnVector { self.inverse() * v } } impl AffineTransformation> for UnitComplex where N: Real, S: OwnedStorage, S::Alloc: OwnedAllocator { 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 UnitComplex where N: Real, S: OwnedStorage, S::Alloc: OwnedAllocator { 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 UnitComplex where N: Real, S: OwnedStorage, S::Alloc: OwnedAllocator { } )*} ); marker_impl!(Isometry, DirectIsometry, OrthogonalTransformation); impl Rotation> for UnitComplex where N: Real, S: OwnedStorage, S::Alloc: OwnedAllocator { #[inline] fn powf(&self, n: N) -> Option { Some(self.powf(n)) } #[inline] fn rotation_between(a: &ColumnVector, b: &ColumnVector) -> Option { Some(Self::rotation_between(a, b)) } #[inline] fn scaled_rotation_between(a: &ColumnVector, b: &ColumnVector, s: N) -> Option { Some(Self::scaled_rotation_between(a, b, s)) } }