Add interpolation logic
This commit is contained in:
parent
97d0354aa9
commit
30a66610ad
43
src/lib.rs
43
src/lib.rs
|
@ -1,13 +1,13 @@
|
|||
use std::fmt::Display;
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct InterpLUT<T> {
|
||||
inner: Vec<(T, T)>,
|
||||
pub struct InterpLUT {
|
||||
inner: Vec<(f64, f64)>,
|
||||
}
|
||||
|
||||
impl InterpLUT<f64> {
|
||||
impl InterpLUT {
|
||||
/// Creates a new, empty table.
|
||||
pub fn new() -> InterpLUT<f64> {
|
||||
pub fn new() -> InterpLUT {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
|
@ -27,9 +27,42 @@ impl InterpLUT<f64> {
|
|||
self.inner.push((m, n));
|
||||
self.sort();
|
||||
}
|
||||
|
||||
fn binary_search(&self, n: &f64) -> Result<usize, usize> {
|
||||
self.inner
|
||||
.binary_search_by(|&(x, _)| x.partial_cmp(n).unwrap_or(std::cmp::Ordering::Equal))
|
||||
}
|
||||
|
||||
impl Display for InterpLUT<f64> {
|
||||
pub fn get(&self, n: f64) -> Option<f64> {
|
||||
let searched = self.binary_search(&n);
|
||||
if let Ok(i) = searched {
|
||||
return Some(self.inner[i].1);
|
||||
} else if let Err(i) = searched {
|
||||
// value was not found
|
||||
if i == 0 || i == self.inner.len() {
|
||||
return None;
|
||||
}
|
||||
let t = Self::inverse_lerp(self.inner[i - 1].0, self.inner[i].0, n);
|
||||
let res = Self::lerp(self.inner[i - 1].1, self.inner[i].1, t);
|
||||
return Some(res);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn inverse_lerp(low: f64, high: f64, n: f64) -> f64 {
|
||||
let total_distance = high - low;
|
||||
let partial_distance = n - low;
|
||||
partial_distance / total_distance
|
||||
}
|
||||
|
||||
fn lerp(low: f64, high: f64, t: f64) -> f64 {
|
||||
let total_distance = high - low;
|
||||
let partial_distance = total_distance * t;
|
||||
low + partial_distance
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for InterpLUT {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let num_digits_largest = self
|
||||
.inner
|
||||
|
|
16
src/main.rs
16
src/main.rs
|
@ -1,16 +1,16 @@
|
|||
use interplut::InterpLUT;
|
||||
|
||||
fn main() {
|
||||
let mut lut: InterpLUT<f64> = InterpLUT::new();
|
||||
let mut lut = InterpLUT::new();
|
||||
|
||||
lut.insert(31.0, 5.0);
|
||||
lut.insert(5.0, 31.0);
|
||||
lut.insert(5.0, 31.0);
|
||||
lut.insert(5.0, 31.0);
|
||||
lut.insert(4.0, 31.0);
|
||||
lut.insert(3.0, 31.0);
|
||||
lut.insert(2.0, 31.0);
|
||||
lut.insert(1.0, 31.0);
|
||||
lut.insert(5.0, 30.2);
|
||||
lut.insert(4.0, 30.0);
|
||||
lut.insert(3.0, 29.0);
|
||||
lut.insert(2.0, 28.0);
|
||||
lut.insert(1.0, 27.0);
|
||||
lut.insert(18.0, 31.0);
|
||||
println!("{}", lut);
|
||||
dbg!(lut.get(0.5));
|
||||
dbg!(lut.get(17.));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue