use alga::general::{AbstractGroup, AbstractLoop, AbstractMagma, AbstractMonoid, AbstractQuasigroup, AbstractSemigroup, Identity, Inverse, Multiplicative, Real}; use alga::linear::{ProjectiveTransformation, Transformation}; use base::{DefaultAllocator, VectorN}; use base::dimension::{DimNameAdd, DimNameSum, U1}; use base::allocator::Allocator; use geometry::{Point, SubTCategoryOf, TCategory, TProjective, Transform}; /* * * Algebraic structures. * */ impl, C> Identity for Transform where C: TCategory, DefaultAllocator: Allocator, DimNameSum>, { #[inline] fn identity() -> Self { Self::identity() } } impl, C> Inverse for Transform where C: SubTCategoryOf, DefaultAllocator: Allocator, DimNameSum>, { #[inline] fn inverse(&self) -> Self { self.clone().inverse() } #[inline] fn inverse_mut(&mut self) { self.inverse_mut() } } impl, C> AbstractMagma for Transform where C: TCategory, DefaultAllocator: Allocator, DimNameSum>, { #[inline] fn operate(&self, rhs: &Self) -> Self { self * rhs } } macro_rules! impl_multiplicative_structures( ($($marker: ident<$operator: ident>),* $(,)*) => {$( impl, C> $marker<$operator> for Transform where C: TCategory, DefaultAllocator: Allocator, DimNameSum> { } )*} ); macro_rules! impl_inversible_multiplicative_structures( ($($marker: ident<$operator: ident>),* $(,)*) => {$( impl, C> $marker<$operator> for Transform where C: SubTCategoryOf, DefaultAllocator: Allocator, DimNameSum> { } )*} ); impl_multiplicative_structures!( AbstractSemigroup, AbstractMonoid, ); impl_inversible_multiplicative_structures!( AbstractQuasigroup, AbstractLoop, AbstractGroup ); /* * * Transformation groups. * */ impl, C> Transformation> for Transform where N: Real, C: TCategory, DefaultAllocator: Allocator, DimNameSum> + Allocator> + Allocator + Allocator, { #[inline] fn transform_point(&self, pt: &Point) -> Point { self * pt } #[inline] fn transform_vector(&self, v: &VectorN) -> VectorN { self * v } } impl, C> ProjectiveTransformation> for Transform where N: Real, C: SubTCategoryOf, DefaultAllocator: Allocator, DimNameSum> + Allocator> + Allocator + Allocator, { #[inline] fn inverse_transform_point(&self, pt: &Point) -> Point { self.inverse() * pt } #[inline] fn inverse_transform_vector(&self, v: &VectorN) -> VectorN { self.inverse() * v } } // FIXME: we need to implement an SVD for this. // // impl, C> AffineTransformation> for Transform // where N: Real, // C: SubTCategoryOf, // DefaultAllocator: Allocator, DimNameSum> + // Allocator + // Allocator { // type PreRotation = Rotation; // type NonUniformScaling = VectorN; // type PostRotation = Rotation; // type Translation = Translation; // // #[inline] // fn decompose(&self) -> (Self::Translation, Self::PostRotation, Self::NonUniformScaling, Self::PreRotation) { // unimplemented!() // } // }