1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
use get_input_index;
use primitive::InterpolationPrimitive;
pub fn cubic_spline_interpolate<T>(input: f32, inputs: &[f32], outputs: &[T], normalize: bool) -> T
where
T: InterpolationPrimitive + Clone,
{
let input_index = match get_input_index(input, inputs) {
Some(index) => index,
None => return outputs[1].clone(),
};
if input_index >= (inputs.len() - 1) {
outputs[outputs.len() - 2].clone()
} else {
let t_diff = inputs[input_index + 1] - inputs[input_index];
let left_index = input_index * 3;
let right_index = (input_index + 1) * 3;
let v = spline(
input,
inputs[input_index],
t_diff,
&outputs[left_index + 1],
&outputs[right_index + 1],
&outputs[left_index + 2].mul(t_diff),
&outputs[right_index].mul(t_diff),
);
if normalize {
v.normalize()
} else {
v
}
}
}
#[inline]
pub(crate) fn spline<D>(t: f32, left_t: f32, t_diff: f32, p0: &D, p1: &D, m0: &D, m1: &D) -> D
where
D: InterpolationPrimitive,
{
let t = (t - left_t) / t_diff;
let t2 = t * t;
let t3 = t2 * t;
p0.mul(2. * t3 - 3. * t2 + 1.)
.add(&m0.mul(t3 - 2. * t2 + t))
.add(&p1.mul(-2. * t3 + 3. * t2))
.add(&m1.mul(t3 - t2))
}