ff_filter/animation/
lerp.rs1pub trait Lerp: Clone {
8 fn lerp(a: &Self, b: &Self, t: f64) -> Self;
10}
11
12impl Lerp for f64 {
13 fn lerp(a: &Self, b: &Self, t: f64) -> Self {
14 a + (b - a) * t
15 }
16}
17
18impl Lerp for (f64, f64) {
19 fn lerp(a: &Self, b: &Self, t: f64) -> Self {
20 (f64::lerp(&a.0, &b.0, t), f64::lerp(&a.1, &b.1, t))
21 }
22}
23
24impl Lerp for (f64, f64, f64) {
25 fn lerp(a: &Self, b: &Self, t: f64) -> Self {
26 (
27 f64::lerp(&a.0, &b.0, t),
28 f64::lerp(&a.1, &b.1, t),
29 f64::lerp(&a.2, &b.2, t),
30 )
31 }
32}
33
34#[cfg(test)]
37mod tests {
38 use super::*;
39
40 #[test]
41 fn lerp_tuple2d_should_interpolate_both_components() {
42 let a = (0.0_f64, 10.0_f64);
43 let b = (100.0_f64, 50.0_f64);
44
45 let mid = <(f64, f64)>::lerp(&a, &b, 0.5);
46 assert!(
47 (mid.0 - 50.0).abs() < f64::EPSILON,
48 "x: expected 50.0, got {}",
49 mid.0
50 );
51 assert!(
52 (mid.1 - 30.0).abs() < f64::EPSILON,
53 "y: expected 30.0, got {}",
54 mid.1
55 );
56
57 let start = <(f64, f64)>::lerp(&a, &b, 0.0);
58 assert!((start.0 - 0.0).abs() < f64::EPSILON);
59 assert!((start.1 - 10.0).abs() < f64::EPSILON);
60
61 let end = <(f64, f64)>::lerp(&a, &b, 1.0);
62 assert!((end.0 - 100.0).abs() < f64::EPSILON);
63 assert!((end.1 - 50.0).abs() < f64::EPSILON);
64 }
65
66 #[test]
67 fn lerp_tuple3d_should_interpolate_all_components() {
68 let a = (0.0_f64, 0.0_f64, 0.0_f64);
69 let b = (255.0_f64, 128.0_f64, 64.0_f64);
70
71 let mid = <(f64, f64, f64)>::lerp(&a, &b, 0.5);
72 assert!(
73 (mid.0 - 127.5).abs() < f64::EPSILON,
74 "r: expected 127.5, got {}",
75 mid.0
76 );
77 assert!(
78 (mid.1 - 64.0).abs() < f64::EPSILON,
79 "g: expected 64.0, got {}",
80 mid.1
81 );
82 assert!(
83 (mid.2 - 32.0).abs() < f64::EPSILON,
84 "b: expected 32.0, got {}",
85 mid.2
86 );
87
88 let start = <(f64, f64, f64)>::lerp(&a, &b, 0.0);
89 assert!((start.0).abs() < f64::EPSILON);
90 assert!((start.1).abs() < f64::EPSILON);
91 assert!((start.2).abs() < f64::EPSILON);
92
93 let end = <(f64, f64, f64)>::lerp(&a, &b, 1.0);
94 assert!((end.0 - 255.0).abs() < f64::EPSILON);
95 assert!((end.1 - 128.0).abs() < f64::EPSILON);
96 assert!((end.2 - 64.0).abs() < f64::EPSILON);
97 }
98}