#![no_std]
#![deny(missing_docs)]
use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
use scalars::{Real, Zero};
pub trait VectorSpace: Sized + Zero + PartialEq
where
Self: Add<Output = Self>
+ Sub<Output = Self>
+ Mul<<Self as VectorSpace>::Scalar, Output = Self>
+ Div<<Self as VectorSpace>::Scalar, Output = Self>
+ Neg<Output = Self>,
{
type Scalar: Real;
}
impl VectorSpace for f32 {
type Scalar = Self;
}
impl VectorSpace for f64 {
type Scalar = Self;
}
pub trait VectorSpaceAssign:
VectorSpace + AddAssign + SubAssign + MulAssign<Self::Scalar> + DivAssign<Self::Scalar>
{
}
impl<T> VectorSpaceAssign for T where
T: VectorSpace + AddAssign + SubAssign + MulAssign<Self::Scalar> + DivAssign<Self::Scalar>
{
}
pub trait AffineSpace: Sub<Output = Self::Diff> + Sized {
type Diff: VectorSpace;
}
impl<T, D> AffineSpace for T
where
T: Sub<Output = D>,
D: VectorSpace,
{
type Diff = D;
}
pub trait Transform<V> {
fn apply_point(&self, point: V) -> V;
}
#[inline]
pub fn interpolate<T>(a: T, b: T, ratio: <T::Diff as VectorSpace>::Scalar) -> T
where
T: Clone + AffineSpace + Add<T::Diff, Output = T>,
{
a.clone() + (b - a) * ratio
}