use alga::general::{ AbstractGroup, AbstractLoop, AbstractMagma, AbstractMonoid, AbstractQuasigroup, AbstractSemigroup, Id, Identity, Multiplicative, RealField, TwoSidedInverse, }; use alga::linear::{ AffineTransformation, DirectIsometry, Isometry, OrthogonalTransformation, ProjectiveTransformation, Rotation, Similarity, Transformation, }; use crate::base::allocator::Allocator; use crate::base::dimension::U2; use crate::base::{DefaultAllocator, Vector2}; use crate::geometry::{Point2, 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 TwoSidedInverse for UnitComplex { #[inline] #[must_use = "Did you mean to use two_sided_inverse_mut()?"] fn two_sided_inverse(&self) -> Self { self.inverse() } #[inline] fn two_sided_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 DefaultAllocator: Allocator, { #[inline] fn transform_point(&self, pt: &Point2) -> Point2 { self.transform_point(pt) } #[inline] fn transform_vector(&self, v: &Vector2) -> Vector2 { self.transform_vector(v) } } impl ProjectiveTransformation> for UnitComplex where DefaultAllocator: Allocator, { #[inline] fn inverse_transform_point(&self, pt: &Point2) -> Point2 { self.inverse_transform_point(pt) } #[inline] fn inverse_transform_vector(&self, v: &Vector2) -> Vector2 { self.inverse_transform_vector(v) } } impl AffineTransformation> for UnitComplex where DefaultAllocator: 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 UnitComplex where DefaultAllocator: 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 UnitComplex where DefaultAllocator: Allocator { } )*} ); marker_impl!(Isometry, DirectIsometry, OrthogonalTransformation); impl Rotation> for UnitComplex where DefaultAllocator: Allocator, { #[inline] fn powf(&self, n: N) -> Option { Some(self.powf(n)) } #[inline] fn rotation_between(a: &Vector2, b: &Vector2) -> Option { Some(Self::rotation_between(a, b)) } #[inline] fn scaled_rotation_between(a: &Vector2, b: &Vector2, s: N) -> Option { Some(Self::scaled_rotation_between(a, b, s)) } }