1use num_traits::{Float, FloatConst};
4
5pub trait Interpolator<Value>: Float + FloatConst {
9 fn lerp(self, start: Value, end: Value) -> Value;
18
19 fn sine_in(self, start: Value, end: Value) -> Value {
20 let it = Self::one() - ((self * Self::PI()) / Self::from(2).unwrap()).cos();
21 it.lerp(start, end)
22 }
23 fn sine_out(self, start: Value, end: Value) -> Value {
24 let it = ((self * Self::PI()) / Self::from(2).unwrap()).sin();
25 it.lerp(start, end)
26 }
27 fn sine_in_out(self, start: Value, end: Value) -> Value {
28 let it = -((self * Self::PI()).cos() - Self::one()) / Self::from(2).unwrap();
29 it.lerp(start, end)
30 }
31
32 fn quad_in(self, start: Value, end: Value) -> Value {
33 let it = self * self;
34 it.lerp(start, end)
35 }
36 fn quad_out(self, start: Value, end: Value) -> Value {
37 let it = Self::one() - (Self::one() - self) * (Self::one() - self);
38 it.lerp(start, end)
39 }
40 fn quad_in_out(self, start: Value, end: Value) -> Value {
41 let two = Self::from(2).unwrap();
42 let it = if self < Self::from(0.5).unwrap() {
43 two * self * self
44 } else {
45 Self::one() - (-two * self + two).powi(2) / two
46 };
47 it.lerp(start, end)
48 }
49
50 }
52
53impl<F> Interpolator<F> for F
54where
55 F: Float + FloatConst,
56{
57 fn lerp(self, start: F, end: F) -> F {
58 start * (Self::one() - self) + end * self
59 }
60}
61
62impl<F, const N: usize> Interpolator<[F; N]> for F
63where
64 F: Float + FloatConst + Copy,
65{
66 fn lerp(self, start: [F; N], end: [F; N]) -> [F; N] {
67 let mut out = [Self::zero(); N];
68 for i in 0..N {
69 out[i] = self.lerp(start[i], end[i]);
70 }
71 out
72 }
73}