mod isometry;
mod rotation;
mod translation;
pub use isometry::Isometry3;
pub use rotation::Rotation3;
pub use translation::Translation3;
use crate::cartesian::xyz::XYZ;
use crate::cartesian::{Direction, Position, Vector};
use crate::centers::ReferenceCenter;
use crate::frames::ReferenceFrame;
use qtty::{LengthUnit, Quantity, Unit};
macro_rules! impl_quantity_mul {
($OpType:ty, $apply_fn:ident, $apply_xyz_fn:ident) => {
impl<U: Unit> std::ops::Mul<[Quantity<U>; 3]> for $OpType {
type Output = [Quantity<U>; 3];
#[inline]
fn mul(self, rhs: [Quantity<U>; 3]) -> [Quantity<U>; 3] {
let [x, y, z] = self.$apply_fn([rhs[0].value(), rhs[1].value(), rhs[2].value()]);
[Quantity::new(x), Quantity::new(y), Quantity::new(z)]
}
}
impl<U: Unit> std::ops::Mul<XYZ<Quantity<U>>> for $OpType {
type Output = XYZ<Quantity<U>>;
#[inline]
fn mul(self, rhs: XYZ<Quantity<U>>) -> XYZ<Quantity<U>> {
XYZ::from_raw(self.$apply_xyz_fn(rhs.to_raw()))
}
}
};
}
impl_quantity_mul!(Rotation3, apply_array, apply_xyz);
impl_quantity_mul!(Translation3, apply_array, apply_xyz);
impl_quantity_mul!(Isometry3, apply_point, apply_xyz);
macro_rules! impl_position_mul {
($OpType:ty, $apply_fn:ident) => {
impl<C, F, U> std::ops::Mul<Position<C, F, U>> for $OpType
where
C: ReferenceCenter,
F: ReferenceFrame,
U: LengthUnit,
C::Params: Clone,
{
type Output = Position<C, F, U>;
#[inline]
fn mul(self, rhs: Position<C, F, U>) -> Position<C, F, U> {
let [x, y, z] = self.$apply_fn([rhs.x().value(), rhs.y().value(), rhs.z().value()]);
Position::new_with_params(
rhs.center_params().clone(),
Quantity::<U>::new(x),
Quantity::<U>::new(y),
Quantity::<U>::new(z),
)
}
}
};
}
impl_position_mul!(Rotation3, apply_array);
impl_position_mul!(Translation3, apply_array);
impl_position_mul!(Isometry3, apply_point);
impl<F, U> std::ops::Mul<Vector<F, U>> for Rotation3
where
F: ReferenceFrame,
U: Unit,
{
type Output = Vector<F, U>;
#[inline]
fn mul(self, rhs: Vector<F, U>) -> Vector<F, U> {
let [x, y, z] = self.apply_array([rhs.x().value(), rhs.y().value(), rhs.z().value()]);
Vector::new(
Quantity::<U>::new(x),
Quantity::<U>::new(y),
Quantity::<U>::new(z),
)
}
}
impl<F: ReferenceFrame> std::ops::Mul<Direction<F>> for Rotation3 {
type Output = Direction<F>;
#[inline]
fn mul(self, rhs: Direction<F>) -> Direction<F> {
let [x, y, z] = self.apply_array([rhs.x(), rhs.y(), rhs.z()]);
Direction::new_unchecked(x, y, z)
}
}