1#![no_std]
2#![deny(missing_docs)]
3use core::{
12 cmp::PartialOrd,
13 ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
14};
15use num_traits::{Zero, real::Real};
16
17pub trait VectorSpace: Zero + PartialEq
20where
21 Self: Add<Output = Self>
22 + Sub<Output = Self>
23 + Mul<<Self as VectorSpace>::Scalar, Output = Self>
24 + Div<<Self as VectorSpace>::Scalar, Output = Self>
25 + Neg<Output = Self>,
26{
27 type Scalar: Real + PartialOrd;
29}
30
31impl VectorSpace for f32 {
32 type Scalar = Self;
33}
34impl VectorSpace for f64 {
35 type Scalar = Self;
36}
37
38pub trait VectorSpaceAssign:
40 VectorSpace + AddAssign + SubAssign + MulAssign<Self::Scalar> + DivAssign<Self::Scalar>
41{
42}
43impl<T> VectorSpaceAssign for T where
44 T: VectorSpace + AddAssign + SubAssign + MulAssign<Self::Scalar> + DivAssign<Self::Scalar>
45{
46}
47
48pub trait AffineSpace: Sub<Output = Self::Diff> + Sized {
50 type Diff: VectorSpace;
52}
53
54impl<T, D> AffineSpace for T
55where
56 T: Sub<Output = D>,
57 D: VectorSpace,
58{
59 type Diff = D;
60}
61
62pub trait Transform<V> {
68 fn apply_point(&self, point: V) -> V;
70}
71
72#[inline]
74pub fn interpolate<T>(a: T, b: T, ratio: <T::Diff as VectorSpace>::Scalar) -> T
75where
76 T: Clone + AffineSpace + Add<T::Diff, Output = T>,
77{
78 a.clone() + (b - a) * ratio
79}