nalgebra/src/geometry/transform_ops.rs

616 lines
27 KiB
Rust
Raw Normal View History

use num::{Zero, One};
use std::ops::{Index, IndexMut, Mul, MulAssign, Div, DivAssign};
use approx::ApproxEq;
use alga::general::{Field, Real, ClosedAdd, ClosedMul, ClosedNeg, SubsetOf};
use core::{Scalar, ColumnVector, OwnedColumnVector, OwnedSquareMatrix};
use core::storage::{Storage, StorageMut, OwnedStorage};
use core::allocator::{Allocator, OwnedAllocator};
use core::dimension::{DimName, DimNameAdd, DimNameSum, U1, U3, U4};
use geometry::{PointBase, OwnedPoint, TransformBase, OwnedTransform, TCategory, TCategoryMul,
SubTCategoryOf, SuperTCategoryOf, TGeneral, TProjective, TAffine, RotationBase,
UnitQuaternionBase, IsometryBase, SimilarityBase, TranslationBase};
2017-02-13 01:17:09 +08:00
/*
*
* In the following, we provide:
* =========================
*
* Index<(usize, usize)>
* IndexMut<(usize, usize)> (where TCategory == TGeneral)
*
* (Operators)
*
* TransformBase × IsometryBase
* TransformBase × RotationBase
* TransformBase × SimilarityBase
* TransformBase × TransformBase
* TransformBase × UnitQuaternion
* FIXME: TransformBase × UnitComplex
* TransformBase × TranslationBase
* TransformBase × ColumnVector
* TransformBase × PointBase
*
* IsometryBase × TransformBase
* RotationBase × TransformBase
* SimilarityBase × TransformBase
* TranslationBase × TransformBase
* UnitQuaternionBase × TransformBase
* FIXME: UnitComplex × TransformBase
*
* FIXME: TransformBase ÷ IsometryBase
* TransformBase ÷ RotationBase
* FIXME: TransformBase ÷ SimilarityBase
* TransformBase ÷ TransformBase
* TransformBase ÷ UnitQuaternion
* TransformBase ÷ TranslationBase
*
* FIXME: IsometryBase ÷ TransformBase
* RotationBase ÷ TransformBase
* FIXME: SimilarityBase ÷ TransformBase
* TranslationBase ÷ TransformBase
* UnitQuaternionBase ÷ TransformBase
* FIXME: UnitComplex ÷ TransformBase
*
*
* (Assignment Operators)
*
*
* TransformBase ×= TransformBase
* TransformBase ×= SimilarityBase
* TransformBase ×= IsometryBase
* TransformBase ×= RotationBase
* TransformBase ×= UnitQuaternionBase
* FIXME: TransformBase ×= UnitComplex
* TransformBase ×= TranslationBase
*
* TransformBase ÷= TransformBase
* FIXME: TransformBase ÷= SimilarityBase
* FIXME: TransformBase ÷= IsometryBase
* TransformBase ÷= RotationBase
* TransformBase ÷= UnitQuaternionBase
* FIXME: TransformBase ÷= UnitComplex
*
*/
/*
*
* Indexing.
*
*/
impl<N, D, S, C: TCategory> Index<(usize, usize)> for TransformBase<N, D, S, C>
where N: Scalar,
D: DimName + DimNameAdd<U1>,
S: Storage<N, DimNameSum<D, U1>, DimNameSum<D, U1>> {
type Output = N;
#[inline]
fn index(&self, ij: (usize, usize)) -> &N {
self.matrix().index(ij)
}
}
// Only general transformations are mutably indexable.
impl<N, D, S> IndexMut<(usize, usize)> for TransformBase<N, D, S, TGeneral>
where N: Scalar,
D: DimName + DimNameAdd<U1>,
S: StorageMut<N, DimNameSum<D, U1>, DimNameSum<D, U1>> {
#[inline]
fn index_mut(&mut self, ij: (usize, usize)) -> &mut N {
self.matrix_mut().index_mut(ij)
}
}
// TransformBase × ColumnVector
md_impl_all!(
Mul, mul where N: Field;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategory
where SA::Alloc: Allocator<N, D, D>
where SA::Alloc: Allocator<N, D, U1>
where SA::Alloc: Allocator<N, U1, D>;
self: TransformBase<N, D, SA, C>, rhs: ColumnVector<N, D, SB>, Output = OwnedColumnVector<N, D, SA::Alloc>;
[val val] => &self * &rhs;
[ref val] => self * &rhs;
[val ref] => &self * rhs;
[ref ref] => {
let transform = self.matrix().fixed_slice::<D, D>(0, 0);
if C::has_normalizer() {
let normalizer = self.matrix().fixed_slice::<U1, D>(D::dim(), 0);
let n = normalizer.tr_dot(&rhs);
if !n.is_zero() {
return transform * (rhs / n);
}
}
transform * rhs
};
);
// TransformBase × PointBase
md_impl_all!(
Mul, mul where N: Field;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategory
where SA::Alloc: Allocator<N, D, D>
where SA::Alloc: Allocator<N, D, U1>
where SA::Alloc: Allocator<N, U1, D>;
self: TransformBase<N, D, SA, C>, rhs: PointBase<N, D, SB>, Output = OwnedPoint<N, D, SA::Alloc>;
[val val] => &self * &rhs;
[ref val] => self * &rhs;
[val ref] => &self * rhs;
[ref ref] => {
let transform = self.matrix().fixed_slice::<D, D>(0, 0);
let translation = self.matrix().fixed_slice::<D, U1>(0, D::dim());
if C::has_normalizer() {
let normalizer = self.matrix().fixed_slice::<U1, D>(D::dim(), 0);
let n = normalizer.tr_dot(&rhs.coords) + unsafe { *self.matrix().get_unchecked(D::dim(), D::dim()) };
if !n.is_zero() {
return transform * (rhs / n) + translation;
}
}
transform * rhs + translation
};
);
// TransformBase × TransformBase
md_impl_all!(
Mul, mul;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (DimNameSum<D, U1>, DimNameSum<D, U1>) for D: DimNameAdd<U1>, CA: TCategoryMul<CB>, CB: TCategory;
self: TransformBase<N, D, SA, CA>, rhs: TransformBase<N, D, SB, CB>, Output = OwnedTransform<N, D, SA::Alloc, CA::Representative>;
[val val] => Self::Output::from_matrix_unchecked(self.unwrap() * rhs.unwrap());
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.unwrap());
[val ref] => Self::Output::from_matrix_unchecked(self.unwrap() * rhs.matrix());
[ref ref] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.matrix());
);
// TransformBase × RotationBase
md_impl_all!(
Mul, mul where N: One;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, D) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>
where SB::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
self: TransformBase<N, D, SA, C>, rhs: RotationBase<N, D, SB>, Output = OwnedTransform<N, D, SA::Alloc, C::Representative>;
[val val] => Self::Output::from_matrix_unchecked(self.unwrap() * rhs.to_homogeneous());
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
[val ref] => Self::Output::from_matrix_unchecked(self.unwrap() * rhs.to_homogeneous());
[ref ref] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
);
// RotationBase × TransformBase
md_impl_all!(
Mul, mul where N: One;
(D, D), (DimNameSum<D, U1>, DimNameSum<D, U1>) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>
where SA::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
self: RotationBase<N, D, SA>, rhs: TransformBase<N, D, SB, C>, Output = OwnedTransform<N, D, SA::Alloc, C::Representative>;
[val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.unwrap());
[ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.unwrap());
[val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
[ref ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
);
// TransformBase × UnitQuaternionBase
md_impl_all!(
Mul, mul where N: Real;
(U4, U4), (U4, U1) for C: TCategoryMul<TAffine>
where SB::Alloc: Allocator<N, U3, U3>
where SB::Alloc: Allocator<N, U4, U4>;
self: TransformBase<N, U3, SA, C>, rhs: UnitQuaternionBase<N, SB>, Output = OwnedTransform<N, U3, SA::Alloc, C::Representative>;
[val val] => Self::Output::from_matrix_unchecked(self.unwrap() * rhs.to_homogeneous());
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
[val ref] => Self::Output::from_matrix_unchecked(self.unwrap() * rhs.to_homogeneous());
[ref ref] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
);
// UnitQuaternionBase × TransformBase
md_impl_all!(
Mul, mul where N: Real;
(U4, U1), (U4, U4) for C: TCategoryMul<TAffine>
where SA::Alloc: Allocator<N, U3, U3>
where SA::Alloc: Allocator<N, U4, U4>;
self: UnitQuaternionBase<N, SA>, rhs: TransformBase<N, U3, SB, C>, Output = OwnedTransform<N, U3, SA::Alloc, C::Representative>;
[val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.unwrap());
[ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.unwrap());
[val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
[ref ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
);
// TransformBase × IsometryBase
md_impl_all!(
Mul, mul where N: Real;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<OwnedSquareMatrix<N, DimNameSum<D, U1>, SB::Alloc> >
where SB::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
self: TransformBase<N, D, SA, C>, rhs: IsometryBase<N, D, SB, R>, Output = OwnedTransform<N, D, SA::Alloc, C::Representative>;
[val val] => Self::Output::from_matrix_unchecked(self.unwrap() * rhs.to_homogeneous());
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
[val ref] => Self::Output::from_matrix_unchecked(self.unwrap() * rhs.to_homogeneous());
[ref ref] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
);
// IsometryBase × TransformBase
md_impl_all!(
Mul, mul where N: Real;
(D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>)
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<OwnedSquareMatrix<N, DimNameSum<D, U1>, SA::Alloc> >
where SA::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
self: IsometryBase<N, D, SA, R>, rhs: TransformBase<N, D, SB, C>, Output = OwnedTransform<N, D, SA::Alloc, C::Representative>;
[val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.unwrap());
[ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.unwrap());
[val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
[ref ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
);
// TransformBase × SimilarityBase
md_impl_all!(
Mul, mul where N: Real;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<OwnedSquareMatrix<N, DimNameSum<D, U1>, SB::Alloc> >
where SB::Alloc: Allocator<N, D, D >
where SB::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
self: TransformBase<N, D, SA, C>, rhs: SimilarityBase<N, D, SB, R>, Output = OwnedTransform<N, D, SA::Alloc, C::Representative>;
[val val] => Self::Output::from_matrix_unchecked(self.unwrap() * rhs.to_homogeneous());
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
[val ref] => Self::Output::from_matrix_unchecked(self.unwrap() * rhs.to_homogeneous());
[ref ref] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
);
// SimilarityBase × TransformBase
md_impl_all!(
Mul, mul where N: Real;
(D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>)
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<OwnedSquareMatrix<N, DimNameSum<D, U1>, SA::Alloc> >
where SA::Alloc: Allocator<N, D, D >
where SA::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
self: SimilarityBase<N, D, SA, R>, rhs: TransformBase<N, D, SB, C>, Output = OwnedTransform<N, D, SA::Alloc, C::Representative>;
[val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.unwrap());
[ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.unwrap());
[val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
[ref ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
);
/*
*
* FIXME: don't explicitly build the homogeneous translation matrix.
* Directly apply the translation, just as in `Matrix::{append,prepend}_translation`. This has not
* been done yet because of the `DimNameDiff` requirement (which is not automatically deduced from
* `DimNameAdd` requirement).
*
*/
// TransformBase × TranslationBase
md_impl_all!(
Mul, mul where N: Real;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>
where SB::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
self: TransformBase<N, D, SA, C>, rhs: TranslationBase<N, D, SB>, Output = OwnedTransform<N, D, SA::Alloc, C::Representative>;
[val val] => Self::Output::from_matrix_unchecked(self.unwrap() * rhs.to_homogeneous());
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
[val ref] => Self::Output::from_matrix_unchecked(self.unwrap() * rhs.to_homogeneous());
[ref ref] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
);
// TranslationBase × TransformBase
md_impl_all!(
Mul, mul where N: Real;
(D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>)
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>
where SA::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
self: TranslationBase<N, D, SA>, rhs: TransformBase<N, D, SB, C>, Output = OwnedTransform<N, D, SA::Alloc, C::Representative>;
[val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.unwrap());
[ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.unwrap());
[val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
[ref ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
);
// TransformBase ÷ TransformBase
md_impl_all!(
Div, div where N: ApproxEq, Field;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (DimNameSum<D, U1>, DimNameSum<D, U1>) for D: DimNameAdd<U1>, CA: TCategoryMul<CB>, CB: SubTCategoryOf<TProjective>;
self: TransformBase<N, D, SA, CA>, rhs: TransformBase<N, D, SB, CB>, Output = OwnedTransform<N, D, SA::Alloc, CA::Representative>;
[val val] => self * rhs.inverse();
[ref val] => self * rhs.inverse();
[val ref] => self * rhs.clone_owned().inverse();
[ref ref] => self * rhs.clone_owned().inverse();
);
// TransformBase ÷ RotationBase
md_impl_all!(
Div, div where N: One;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, D) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>
where SB::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
self: TransformBase<N, D, SA, C>, rhs: RotationBase<N, D, SB>, Output = OwnedTransform<N, D, SA::Alloc, C::Representative>;
[val val] => self * rhs.inverse();
[ref val] => self * rhs.inverse();
[val ref] => self * rhs.inverse();
[ref ref] => self * rhs.inverse();
);
// RotationBase ÷ TransformBase
md_impl_all!(
Div, div where N: One;
(D, D), (DimNameSum<D, U1>, DimNameSum<D, U1>) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>
where SA::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
self: RotationBase<N, D, SA>, rhs: TransformBase<N, D, SB, C>, Output = OwnedTransform<N, D, SA::Alloc, C::Representative>;
[val val] => self.inverse() * rhs;
[ref val] => self.inverse() * rhs;
[val ref] => self.inverse() * rhs;
[ref ref] => self.inverse() * rhs;
);
// TransformBase ÷ UnitQuaternionBase
md_impl_all!(
Div, div where N: Real;
(U4, U4), (U4, U1) for C: TCategoryMul<TAffine>
where SB::Alloc: Allocator<N, U3, U3>
where SB::Alloc: Allocator<N, U4, U4>;
self: TransformBase<N, U3, SA, C>, rhs: UnitQuaternionBase<N, SB>, Output = OwnedTransform<N, U3, SA::Alloc, C::Representative>;
[val val] => self * rhs.inverse();
[ref val] => self * rhs.inverse();
[val ref] => self * rhs.inverse();
[ref ref] => self * rhs.inverse();
);
// UnitQuaternionBase ÷ TransformBase
md_impl_all!(
Div, div where N: Real;
(U4, U1), (U4, U4) for C: TCategoryMul<TAffine>
where SA::Alloc: Allocator<N, U3, U3>
where SA::Alloc: Allocator<N, U4, U4>;
self: UnitQuaternionBase<N, SA>, rhs: TransformBase<N, U3, SB, C>, Output = OwnedTransform<N, U3, SA::Alloc, C::Representative>;
[val val] => self.inverse() * rhs;
[ref val] => self.inverse() * rhs;
[val ref] => self.inverse() * rhs;
[ref ref] => self.inverse() * rhs;
);
// // TransformBase ÷ IsometryBase
// md_impl_all!(
// Div, div where N: Real;
// (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
// for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<OwnedSquareMatrix<N, DimNameSum<D, U1>, SB::Alloc> >
// where SB::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
// self: TransformBase<N, D, SA, C>, rhs: IsometryBase<N, D, SB, R>, Output = OwnedTransform<N, D, SA::Alloc, C::Representative>;
// [val val] => Self::Output::from_matrix_unchecked(self.unwrap() * rhs.inverse().to_homogeneous());
// [ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.inverse().to_homogeneous());
// [val ref] => Self::Output::from_matrix_unchecked(self.unwrap() * rhs.inverse().to_homogeneous());
// [ref ref] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.inverse().to_homogeneous());
// );
// // IsometryBase ÷ TransformBase
// md_impl_all!(
// Div, div where N: Real;
// (D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>)
// for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<OwnedSquareMatrix<N, DimNameSum<D, U1>, SA::Alloc> >
// where SA::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
// self: IsometryBase<N, D, SA, R>, rhs: TransformBase<N, D, SB, C>, Output = OwnedTransform<N, D, SA::Alloc, C::Representative>;
// [val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.unwrap());
// [ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.unwrap());
// [val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
// [ref ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
// );
// // TransformBase ÷ SimilarityBase
// md_impl_all!(
// Div, div where N: Real;
// (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
// for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<OwnedSquareMatrix<N, DimNameSum<D, U1>, SB::Alloc> >
// where SB::Alloc: Allocator<N, D, D >
// where SB::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
// self: TransformBase<N, D, SA, C>, rhs: SimilarityBase<N, D, SB, R>, Output = OwnedTransform<N, D, SA::Alloc, C::Representative>;
// [val val] => Self::Output::from_matrix_unchecked(self.unwrap() * rhs.to_homogeneous());
// [ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
// [val ref] => Self::Output::from_matrix_unchecked(self.unwrap() * rhs.to_homogeneous());
// [ref ref] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
// );
// // SimilarityBase ÷ TransformBase
// md_impl_all!(
// Div, div where N: Real;
// (D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>)
// for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>, R: SubsetOf<OwnedSquareMatrix<N, DimNameSum<D, U1>, SA::Alloc> >
// where SA::Alloc: Allocator<N, D, D >
// where SA::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
// self: SimilarityBase<N, D, SA, R>, rhs: TransformBase<N, D, SB, C>, Output = OwnedTransform<N, D, SA::Alloc, C::Representative>;
// [val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.unwrap());
// [ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.unwrap());
// [val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
// [ref ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
// );
// TransformBase ÷ TranslationBase
md_impl_all!(
Div, div where N: Real;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>
where SB::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
self: TransformBase<N, D, SA, C>, rhs: TranslationBase<N, D, SB>, Output = OwnedTransform<N, D, SA::Alloc, C::Representative>;
[val val] => self * rhs.inverse();
[ref val] => self * rhs.inverse();
[val ref] => self * rhs.inverse();
[ref ref] => self * rhs.inverse();
);
// TranslationBase ÷ TransformBase
md_impl_all!(
Div, div where N: Real;
(D, U1), (DimNameSum<D, U1>, DimNameSum<D, U1>)
for D: DimNameAdd<U1>, C: TCategoryMul<TAffine>
where SA::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
self: TranslationBase<N, D, SA>, rhs: TransformBase<N, D, SB, C>, Output = OwnedTransform<N, D, SA::Alloc, C::Representative>;
[val val] => self.inverse() * rhs;
[ref val] => self.inverse() * rhs;
[val ref] => self.inverse() * rhs;
[ref ref] => self.inverse() * rhs;
);
// TransformBase ×= TransformBase
md_assign_impl_all!(
MulAssign, mul_assign;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (DimNameSum<D, U1>, DimNameSum<D, U1>) for D: DimNameAdd<U1>, CA: TCategory, CB: SubTCategoryOf<CA>;
self: TransformBase<N, D, SA, CA>, rhs: TransformBase<N, D, SB, CB>;
[val] => *self.matrix_mut_unchecked() *= rhs.unwrap();
[ref] => *self.matrix_mut_unchecked() *= rhs.matrix();
);
// TransformBase ×= SimilarityBase
md_assign_impl_all!(
MulAssign, mul_assign;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
for D: DimNameAdd<U1>, C: TCategory, R: SubsetOf<OwnedSquareMatrix<N, DimNameSum<D, U1>, SB::Alloc> >
where SB::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >
where SB::Alloc: Allocator<N, D, D>;
self: TransformBase<N, D, SA, C>, rhs: SimilarityBase<N, D, SB, R>;
[val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
[ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
);
// TransformBase ×= IsometryBase
md_assign_impl_all!(
MulAssign, mul_assign;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
for D: DimNameAdd<U1>, C: TCategory, R: SubsetOf<OwnedSquareMatrix<N, DimNameSum<D, U1>, SB::Alloc> >
where SB::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
self: TransformBase<N, D, SA, C>, rhs: IsometryBase<N, D, SB, R>;
[val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
[ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
);
/*
*
* FIXME: don't explicitly build the homogeneous translation matrix.
* Directly apply the translation, just as in `Matrix::{append,prepend}_translation`. This has not
* been done yet because of the `DimNameDiff` requirement (which is not automatically deduced from
* `DimNameAdd` requirement).
*
*/
// TransformBase ×= TranslationBase
md_assign_impl_all!(
MulAssign, mul_assign where N: One;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategory
where SB::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
self: TransformBase<N, D, SA, C>, rhs: TranslationBase<N, D, SB>;
[val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
[ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
);
// TransformBase ×= RotationBase
md_assign_impl_all!(
MulAssign, mul_assign where N: One;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, D) for D: DimNameAdd<U1>, C: TCategory
where SB::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
self: TransformBase<N, D, SA, C>, rhs: RotationBase<N, D, SB>;
[val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
[ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
);
// TransformBase ×= UnitQuaternionBase
md_assign_impl_all!(
MulAssign, mul_assign where N: Real;
(U4, U4), (U4, U1) for C: TCategory
where SB::Alloc: Allocator<N, U3, U3>
where SB::Alloc: Allocator<N, U4, U4>;
self: TransformBase<N, U3, SA, C>, rhs: UnitQuaternionBase<N, SB>;
[val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
[ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
);
// TransformBase ÷= TransformBase
md_assign_impl_all!(
DivAssign, div_assign where N: Field, ApproxEq;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (DimNameSum<D, U1>, DimNameSum<D, U1>)
for D: DimNameAdd<U1>, CA: SuperTCategoryOf<CB>, CB: SubTCategoryOf<TProjective>;
self: TransformBase<N, D, SA, CA>, rhs: TransformBase<N, D, SB, CB>;
[val] => *self *= rhs.clone_owned().inverse();
[ref] => *self *= rhs.clone_owned().inverse();
);
// // TransformBase ÷= SimilarityBase
// md_assign_impl_all!(
// DivAssign, div_assign;
// (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
// for D: DimNameAdd<U1>, C: TCategory, R: SubsetOf<OwnedSquareMatrix<N, DimNameSum<D, U1>, SB::Alloc> >
// where SB::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >
// where SB::Alloc: Allocator<N, D, D>;
// self: TransformBase<N, D, SA, C>, rhs: SimilarityBase<N, D, SB, R>;
// [val] => *self *= rhs.inverse();
// [ref] => *self *= rhs.inverse();
// );
//
//
// // TransformBase ÷= IsometryBase
// md_assign_impl_all!(
// DivAssign, div_assign;
// (DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1)
// for D: DimNameAdd<U1>, C: TCategory, R: SubsetOf<OwnedSquareMatrix<N, DimNameSum<D, U1>, SB::Alloc> >
// where SB::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
// self: TransformBase<N, D, SA, C>, rhs: IsometryBase<N, D, SB, R>;
// [val] => *self *= rhs.inverse();
// [ref] => *self *= rhs.inverse();
// );
// TransformBase ÷= TranslationBase
md_assign_impl_all!(
DivAssign, div_assign where N: One, ClosedNeg;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, U1) for D: DimNameAdd<U1>, C: TCategory
where SB::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
self: TransformBase<N, D, SA, C>, rhs: TranslationBase<N, D, SB>;
[val] => *self *= rhs.inverse();
[ref] => *self *= rhs.inverse();
);
// TransformBase ÷= RotationBase
md_assign_impl_all!(
DivAssign, div_assign where N: One;
(DimNameSum<D, U1>, DimNameSum<D, U1>), (D, D) for D: DimNameAdd<U1>, C: TCategory
where SB::Alloc: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1> >;
self: TransformBase<N, D, SA, C>, rhs: RotationBase<N, D, SB>;
[val] => *self *= rhs.inverse();
[ref] => *self *= rhs.inverse();
);
// TransformBase ÷= UnitQuaternionBase
md_assign_impl_all!(
DivAssign, div_assign where N: Real;
(U4, U4), (U4, U1) for C: TCategory
where SB::Alloc: Allocator<N, U3, U3>
where SB::Alloc: Allocator<N, U4, U4>;
self: TransformBase<N, U3, SA, C>, rhs: UnitQuaternionBase<N, SB>;
[val] => *self *= rhs.inverse();
[ref] => *self *= rhs.inverse();
);