index/utils/
interpolation.rs

1use wasm_bindgen::prelude::*;
2
3/// Linearly interpolates between two values given a progress value.
4#[wasm_bindgen(return_description = "The interpolated value.")]
5pub fn lerp(
6    #[wasm_bindgen(param_description = "The start value.")]
7    a: f32,
8    #[wasm_bindgen(param_description = "The end value.")]
9    b: f32,
10    #[wasm_bindgen(param_description = "The progress value.")]
11    t: f32
12) -> f32 {
13    a + (b - a) * t
14}
15
16/// Returns the progress value between two numbers given an interpolated value.
17#[wasm_bindgen(return_description = "The progress value.")]
18pub fn inverse_lerp(
19    #[wasm_bindgen(param_description = "The start value.")]
20    a: f32,
21    #[wasm_bindgen(param_description = "The end value.")]
22    b: f32,
23    #[wasm_bindgen(param_description = "The value to find the progress of.")]
24    value: f32) -> f32 {
25    if a == b {
26        return 0.0;
27    }
28    (value - a) / (b - a)
29}
30
31/// A variant of lerp that returns the integer index and remainder. Useful for discrete interpolation.
32#[wasm_bindgen]
33pub struct IntegerLerp {
34    /// The integer index.
35    index: i32,
36    /// The remainder.
37    remainder: f32,
38}
39
40#[wasm_bindgen]
41impl IntegerLerp {
42    /// Interpolates between two values and returns the integer index and remainder.
43    #[wasm_bindgen(constructor, return_description = "A class containing the integer index and remainder.")]
44    pub fn new(
45        #[wasm_bindgen(param_description = "The start value.")]
46        a: f32,
47        #[wasm_bindgen(param_description = "The end value.")]
48        b: f32,
49        #[wasm_bindgen(param_description = "The progress value.")]
50        t: f32
51    ) -> IntegerLerp {
52        if t >= 1.0 {
53            return IntegerLerp { index: (b - 1.0).floor() as i32, remainder: 1.0 };
54        }
55        if t <= 0.0 {
56            return IntegerLerp { index: a.floor() as i32, remainder: 0.0 };
57        }
58        let value = lerp(a, b, t);
59        let index = value.floor() as i32;
60        let remainder = value - index as f32;
61        IntegerLerp { index, remainder }
62    }
63
64    /// Gets the integer index.
65    #[wasm_bindgen(getter, return_description = "The integer index.")]
66    pub fn index(&self) -> i32 {
67        self.index
68    }
69
70    /// Gets the remainder.
71    #[wasm_bindgen(getter, return_description = "The remainder.")]
72    pub fn remainder(&self) -> f32 {
73        self.remainder
74    }
75}