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