spatial-motion 0.2.0

Generic spatial transforms and movement, built on geometric algebra traits
Documentation
use derive_more::{Add, AddAssign, Neg, Sub, SubAssign};
use scalars::Zero;
use vector_space::VectorSpace;

use core::ops::{Div, DivAssign, Mul, MulAssign};

#[derive(Copy, Clone, Debug, Add, AddAssign, Sub, SubAssign, Neg, PartialEq, Eq)]
pub struct Movement<V, B> {
    pub velocity: V,
    pub spin: B,
}

impl<V: Zero, B: Zero> Zero for Movement<V, B> {
    fn zero() -> Self {
        Self {
            velocity: V::zero(),
            spin: B::zero(),
        }
    }

    fn is_zero(&self) -> bool {
        self.velocity.is_zero() && self.spin.is_zero()
    }
}

impl<V, B> Mul<V::Scalar> for Movement<V, B>
where
    V: VectorSpace,
    B: VectorSpace<Scalar = V::Scalar>,
{
    type Output = Self;

    fn mul(self, scalar: V::Scalar) -> Self {
        Self {
            velocity: self.velocity * scalar,
            spin: self.spin * scalar,
        }
    }
}

impl<V, B> Div<V::Scalar> for Movement<V, B>
where
    V: VectorSpace,
    B: VectorSpace<Scalar = V::Scalar>,
{
    type Output = Self;

    fn div(self, scalar: V::Scalar) -> Self {
        Self {
            velocity: self.velocity / scalar,
            spin: self.spin / scalar,
        }
    }
}

impl<V, B> MulAssign<V::Scalar> for Movement<V, B>
where
    V: VectorSpace + MulAssign<V::Scalar>,
    B: VectorSpace<Scalar = V::Scalar> + MulAssign<V::Scalar>,
{
    fn mul_assign(&mut self, scalar: V::Scalar) {
        self.velocity *= scalar;
        self.spin *= scalar;
    }
}

impl<V, B> DivAssign<V::Scalar> for Movement<V, B>
where
    V: VectorSpace + DivAssign<V::Scalar>,
    B: VectorSpace<Scalar = V::Scalar> + DivAssign<V::Scalar>,
{
    fn div_assign(&mut self, scalar: V::Scalar) {
        self.velocity /= scalar;
        self.spin /= scalar;
    }
}