1#![no_std]
2#![deny(missing_docs)]
3use core::{
10 cmp::PartialOrd,
11 ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
12};
13use num_traits::{Zero, real::Real};
14
15pub trait VectorSpace: Zero + PartialEq
18where
19 Self: Add<Output = Self>
20 + Sub<Output = Self>
21 + Mul<<Self as VectorSpace>::Scalar, Output = Self>
22 + Div<<Self as VectorSpace>::Scalar, Output = Self>
23 + Neg<Output = Self>,
24{
25 type Scalar: Real + PartialOrd;
27}
28
29impl VectorSpace for f32 {
30 type Scalar = Self;
31}
32impl VectorSpace for f64 {
33 type Scalar = Self;
34}
35
36pub trait VectorSpaceAssign:
38 VectorSpace + AddAssign + SubAssign + MulAssign<Self::Scalar> + DivAssign<Self::Scalar>
39{
40}
41impl<T> VectorSpaceAssign for T where
42 T: VectorSpace + AddAssign + SubAssign + MulAssign<Self::Scalar> + DivAssign<Self::Scalar>
43{
44}
45
46pub trait AffineSpace: Sub<Output = Self::Diff> + Sized {
48 type Diff: VectorSpace;
50}
51
52impl<T, D> AffineSpace for T
53where
54 T: Sub<Output = D>,
55 D: VectorSpace,
56{
57 type Diff = D;
58}
59
60#[inline]
62pub fn interpolate<T>(a: T, b: T, ratio: <T::Diff as VectorSpace>::Scalar) -> T
63where
64 T: Clone + AffineSpace + Add<T::Diff, Output = T>,
65{
66 a.clone() + (b - a) * ratio
67}