nalgebra/src/geometry/unit_complex_ops.rs
2017-02-12 18:17:09 +01:00

396 lines
12 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use std::ops::{Mul, MulAssign, Div, DivAssign};
use alga::general::Real;
use core::{Unit, ColumnVector, OwnedColumnVector};
use core::dimension::{U1, U2};
use core::storage::{Storage, OwnedStorage};
use core::allocator::OwnedAllocator;
use geometry::{UnitComplex, RotationBase,
PointBase, OwnedPoint,
IsometryBase, OwnedIsometryBase,
SimilarityBase, OwnedSimilarityBase,
TranslationBase};
/*
* This file provides:
* ===================
*
* UnitComplex × UnitComplex
* UnitComplex × RotationBase -> UnitComplex
* RotationBase × UnitComplex -> UnitComplex
*
* UnitComplex ÷ UnitComplex
* UnitComplex ÷ RotationBase -> UnitComplex
* RotationBase ÷ UnitComplex -> UnitComplex
*
*
* UnitComplex × PointBase
* UnitComplex × ColumnVector
* UnitComplex × Unit<T>
*
* UnitComplex × IsometryBase<UnitComplex>
* UnitComplex × SimilarityBase<UnitComplex>
* UnitComplex × TranslationBase -> IsometryBase<UnitComplex>
*
* NOTE: -UnitComplex is already provided by `Unit<T>`.
*
* (Assignment Operators)
*
* UnitComplex ×= UnitComplex
* UnitComplex ×= RotationBase
*
* UnitComplex ÷= UnitComplex
* UnitComplex ÷= RotationBase
*
* RotationBase ×= UnitComplex
* RotationBase ÷= UnitComplex
*
*/
// UnitComplex × UnitComplex
impl<N: Real> Mul<UnitComplex<N>> for UnitComplex<N> {
type Output = UnitComplex<N>;
#[inline]
fn mul(self, rhs: UnitComplex<N>) -> UnitComplex<N> {
Unit::new_unchecked(self.unwrap() * rhs.unwrap())
}
}
impl<'a, N: Real> Mul<UnitComplex<N>> for &'a UnitComplex<N> {
type Output = UnitComplex<N>;
#[inline]
fn mul(self, rhs: UnitComplex<N>) -> UnitComplex<N> {
Unit::new_unchecked(self.complex() * rhs.unwrap())
}
}
impl<'b, N: Real> Mul<&'b UnitComplex<N>> for UnitComplex<N> {
type Output = UnitComplex<N>;
#[inline]
fn mul(self, rhs: &'b UnitComplex<N>) -> UnitComplex<N> {
Unit::new_unchecked(self.unwrap() * rhs.complex())
}
}
impl<'a, 'b, N: Real> Mul<&'b UnitComplex<N>> for &'a UnitComplex<N> {
type Output = UnitComplex<N>;
#[inline]
fn mul(self, rhs: &'b UnitComplex<N>) -> UnitComplex<N> {
Unit::new_unchecked(self.complex() * rhs.complex())
}
}
// UnitComplex ÷ UnitComplex
impl<N: Real> Div<UnitComplex<N>> for UnitComplex<N> {
type Output = UnitComplex<N>;
#[inline]
fn div(self, rhs: UnitComplex<N>) -> UnitComplex<N> {
Unit::new_unchecked(self.unwrap() * rhs.conjugate().unwrap())
}
}
impl<'a, N: Real> Div<UnitComplex<N>> for &'a UnitComplex<N> {
type Output = UnitComplex<N>;
#[inline]
fn div(self, rhs: UnitComplex<N>) -> UnitComplex<N> {
Unit::new_unchecked(self.complex() * rhs.conjugate().unwrap())
}
}
impl<'b, N: Real> Div<&'b UnitComplex<N>> for UnitComplex<N> {
type Output = UnitComplex<N>;
#[inline]
fn div(self, rhs: &'b UnitComplex<N>) -> UnitComplex<N> {
Unit::new_unchecked(self.unwrap() * rhs.conjugate().unwrap())
}
}
impl<'a, 'b, N: Real> Div<&'b UnitComplex<N>> for &'a UnitComplex<N> {
type Output = UnitComplex<N>;
#[inline]
fn div(self, rhs: &'b UnitComplex<N>) -> UnitComplex<N> {
Unit::new_unchecked(self.complex() * rhs.conjugate().unwrap())
}
}
macro_rules! complex_op_impl(
($Op: ident, $op: ident;
($RDim: ident, $CDim: ident);
$lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Result: ty;
$action: expr; $($lives: tt),*) => {
impl<$($lives ,)* N, S> $Op<$Rhs> for $Lhs
where N: Real,
S: Storage<N, $RDim, $CDim> {
type Output = $Result;
#[inline]
fn $op($lhs, $rhs: $Rhs) -> Self::Output {
$action
}
}
}
);
macro_rules! complex_op_impl_all(
($Op: ident, $op: ident;
($RDim: ident, $CDim: ident);
$lhs: ident: $Lhs: ty, $rhs: ident: $Rhs: ty, Output = $Result: ty;
[val val] => $action_val_val: expr;
[ref val] => $action_ref_val: expr;
[val ref] => $action_val_ref: expr;
[ref ref] => $action_ref_ref: expr;) => {
complex_op_impl!($Op, $op;
($RDim, $CDim);
$lhs: $Lhs, $rhs: $Rhs, Output = $Result;
$action_val_val; );
complex_op_impl!($Op, $op;
($RDim, $CDim);
$lhs: &'a $Lhs, $rhs: $Rhs, Output = $Result;
$action_ref_val; 'a);
complex_op_impl!($Op, $op;
($RDim, $CDim);
$lhs: $Lhs, $rhs: &'b $Rhs, Output = $Result;
$action_val_ref; 'b);
complex_op_impl!($Op, $op;
($RDim, $CDim);
$lhs: &'a $Lhs, $rhs: &'b $Rhs, Output = $Result;
$action_ref_ref; 'a, 'b);
}
);
// UnitComplex × RotationBase
complex_op_impl_all!(
Mul, mul;
(U2, U2);
self: UnitComplex<N>, rhs: RotationBase<N, U2, S>, Output = UnitComplex<N>;
[val val] => &self * &rhs;
[ref val] => self * &rhs;
[val ref] => &self * rhs;
[ref ref] => self * UnitComplex::from_rotation_matrix(rhs);
);
// UnitComplex ÷ RotationBase
complex_op_impl_all!(
Div, div;
(U2, U2);
self: UnitComplex<N>, rhs: RotationBase<N, U2, S>, Output = UnitComplex<N>;
[val val] => &self / &rhs;
[ref val] => self / &rhs;
[val ref] => &self / rhs;
[ref ref] => self * UnitComplex::from_rotation_matrix(rhs).inverse();
);
// RotationBase × UnitComplex
complex_op_impl_all!(
Mul, mul;
(U2, U2);
self: RotationBase<N, U2, S>, rhs: UnitComplex<N>, Output = UnitComplex<N>;
[val val] => &self * &rhs;
[ref val] => self * &rhs;
[val ref] => &self * rhs;
[ref ref] => UnitComplex::from_rotation_matrix(self) * rhs;
);
// RotationBase ÷ UnitComplex
complex_op_impl_all!(
Div, div;
(U2, U2);
self: RotationBase<N, U2, S>, rhs: UnitComplex<N>, Output = UnitComplex<N>;
[val val] => &self / &rhs;
[ref val] => self / &rhs;
[val ref] => &self / rhs;
[ref ref] => UnitComplex::from_rotation_matrix(self) * rhs.inverse();
);
// UnitComplex × PointBase
complex_op_impl_all!(
Mul, mul;
(U2, U1);
self: UnitComplex<N>, rhs: PointBase<N, U2, S>, Output = OwnedPoint<N, U2, S::Alloc>;
[val val] => &self * &rhs;
[ref val] => self * &rhs;
[val ref] => &self * rhs;
[ref ref] => PointBase::from_coordinates(self * &rhs.coords);
);
// UnitComplex × ColumnVector
complex_op_impl_all!(
Mul, mul;
(U2, U1);
self: UnitComplex<N>, rhs: ColumnVector<N, U2, S>, Output = OwnedColumnVector<N, U2, S::Alloc>;
[val val] => &self * &rhs;
[ref val] => self * &rhs;
[val ref] => &self * rhs;
[ref ref] => {
let i = self.as_ref().im;
let r = self.as_ref().re;
OwnedColumnVector::<_, U2, S::Alloc>::new(r * rhs[0] - i * rhs[1], i * rhs[0] + r * rhs[1])
};
);
// UnitComplex × Unit<Vector>
complex_op_impl_all!(
Mul, mul;
(U2, U1);
self: UnitComplex<N>, rhs: Unit<ColumnVector<N, U2, S>>, Output = Unit<OwnedColumnVector<N, U2, S::Alloc>>;
[val val] => &self * &rhs;
[ref val] => self * &rhs;
[val ref] => &self * rhs;
[ref ref] => Unit::new_unchecked(self * rhs.as_ref());
);
// UnitComplex × IsometryBase<UnitComplex>
complex_op_impl_all!(
Mul, mul;
(U2, U1);
self: UnitComplex<N>, rhs: IsometryBase<N, U2, S, UnitComplex<N>>,
Output = OwnedIsometryBase<N, U2, S::Alloc, UnitComplex<N>>;
[val val] => &self * &rhs;
[ref val] => self * &rhs;
[val ref] => &self * rhs;
[ref ref] => {
let shift = self * &rhs.translation.vector;
IsometryBase::from_parts(TranslationBase::from_vector(shift), self * &rhs.rotation)
};
);
// UnitComplex × SimilarityBase<UnitComplex>
complex_op_impl_all!(
Mul, mul;
(U2, U1);
self: UnitComplex<N>, rhs: SimilarityBase<N, U2, S, UnitComplex<N>>,
Output = OwnedSimilarityBase<N, U2, S::Alloc, UnitComplex<N>>;
[val val] => &self * &rhs;
[ref val] => self * &rhs;
[val ref] => &self * rhs;
[ref ref] => SimilarityBase::from_isometry(self * &rhs.isometry, rhs.scaling());
);
// UnitComplex × TranslationBase
complex_op_impl_all!(
Mul, mul;
(U2, U1);
self: UnitComplex<N>, rhs: TranslationBase<N, U2, S>,
Output = OwnedIsometryBase<N, U2, S::Alloc, UnitComplex<N>>;
[val val] => IsometryBase::from_parts(TranslationBase::from_vector(&self * rhs.vector), self);
[ref val] => IsometryBase::from_parts(TranslationBase::from_vector( self * rhs.vector), self.clone());
[val ref] => IsometryBase::from_parts(TranslationBase::from_vector(&self * &rhs.vector), self);
[ref ref] => IsometryBase::from_parts(TranslationBase::from_vector( self * &rhs.vector), self.clone());
);
// UnitComplex ×= UnitComplex
impl<N: Real> MulAssign<UnitComplex<N>> for UnitComplex<N> {
#[inline]
fn mul_assign(&mut self, rhs: UnitComplex<N>) {
*self = &*self * rhs
}
}
impl<'b, N: Real> MulAssign<&'b UnitComplex<N>> for UnitComplex<N> {
#[inline]
fn mul_assign(&mut self, rhs: &'b UnitComplex<N>) {
*self = &*self * rhs
}
}
// UnitComplex /= UnitComplex
impl<N: Real> DivAssign<UnitComplex<N>> for UnitComplex<N> {
#[inline]
fn div_assign(&mut self, rhs: UnitComplex<N>) {
*self = &*self / rhs
}
}
impl<'b, N: Real> DivAssign<&'b UnitComplex<N>> for UnitComplex<N> {
#[inline]
fn div_assign(&mut self, rhs: &'b UnitComplex<N>) {
*self = &*self / rhs
}
}
// UnitComplex ×= RotationBase
impl<N: Real, S: Storage<N, U2, U2>> MulAssign<RotationBase<N, U2, S>> for UnitComplex<N> {
#[inline]
fn mul_assign(&mut self, rhs: RotationBase<N, U2, S>) {
*self = &*self * rhs
}
}
impl<'b, N: Real, S: Storage<N, U2, U2>> MulAssign<&'b RotationBase<N, U2, S>> for UnitComplex<N> {
#[inline]
fn mul_assign(&mut self, rhs: &'b RotationBase<N, U2, S>) {
*self = &*self * rhs
}
}
// UnitComplex ÷= RotationBase
impl<N: Real, S: Storage<N, U2, U2>> DivAssign<RotationBase<N, U2, S>> for UnitComplex<N> {
#[inline]
fn div_assign(&mut self, rhs: RotationBase<N, U2, S>) {
*self = &*self / rhs
}
}
impl<'b, N: Real, S: Storage<N, U2, U2>> DivAssign<&'b RotationBase<N, U2, S>> for UnitComplex<N> {
#[inline]
fn div_assign(&mut self, rhs: &'b RotationBase<N, U2, S>) {
*self = &*self / rhs
}
}
// RotationBase ×= UnitComplex
impl<N: Real, S> MulAssign<UnitComplex<N>> for RotationBase<N, U2, S>
where S: OwnedStorage<N, U2, U2>,
S::Alloc: OwnedAllocator<N, U2, U2, S> {
#[inline]
fn mul_assign(&mut self, rhs: UnitComplex<N>) {
self.mul_assign(rhs.to_rotation_matrix())
}
}
impl<'b, N: Real, S: Storage<N, U2, U2>> MulAssign<&'b UnitComplex<N>> for RotationBase<N, U2, S>
where S: OwnedStorage<N, U2, U2>,
S::Alloc: OwnedAllocator<N, U2, U2, S> {
#[inline]
fn mul_assign(&mut self, rhs: &'b UnitComplex<N>) {
self.mul_assign(rhs.to_rotation_matrix())
}
}
// RotationBase ÷= UnitComplex
impl<N: Real, S> DivAssign<UnitComplex<N>> for RotationBase<N, U2, S>
where S: OwnedStorage<N, U2, U2>,
S::Alloc: OwnedAllocator<N, U2, U2, S> {
#[inline]
fn div_assign(&mut self, rhs: UnitComplex<N>) {
self.div_assign(rhs.to_rotation_matrix())
}
}
impl<'b, N: Real, S: Storage<N, U2, U2>> DivAssign<&'b UnitComplex<N>> for RotationBase<N, U2, S>
where S: OwnedStorage<N, U2, U2>,
S::Alloc: OwnedAllocator<N, U2, U2, S> {
#[inline]
fn div_assign(&mut self, rhs: &'b UnitComplex<N>) {
self.div_assign(rhs.to_rotation_matrix())
}
}