Skip to content

Instantly share code, notes, and snippets.

@laundmo
Created December 28, 2023 14:47
Show Gist options
  • Save laundmo/cb06630109e5e1100f5a2758dfb67cfd to your computer and use it in GitHub Desktop.
Save laundmo/cb06630109e5e1100f5a2758dfb67cfd to your computer and use it in GitHub Desktop.
lerp, inverse_lerp and remap in Rust
trait Lerp<T> {
fn lerp(self, from: T, to: T) -> T;
fn inv_lerp(self, from: T, to: T) -> T;
fn remap(self, from_range: (T, T), to_range: (T, T)) -> T;
}
macro_rules! lerp_impl {
($one:literal, $typ:ty) => {
impl Lerp<$typ> for $typ {
#[inline(always)]
fn lerp(self, from: $typ, to: $typ) -> $typ {
//! Linear interpolate on the scale given by a to b, using t as the point on that scale.
($one - self) * from + self * to
}
#[inline(always)]
fn inv_lerp(self, from: $typ, to: $typ) -> $typ {
//! Inverse Linar Interpolation, get the fraction between a and b on which v resides.
(self - from) / (to - from)
}
#[inline(always)]
fn remap(self, from_range: ($typ, $typ), to_range: ($typ, $typ)) -> $typ {
//! Remap values from one linear scale to another, a combination of lerp and inv_lerp.
//! i_range is the scale of the original value,
//! o_range is the scale of the resulting value.
self.inv_lerp(from_range.0, from_range.1)
.lerp(to_range.0, to_range.1)
}
}
};
}
lerp_impl!(1., f32);
lerp_impl!(1., f64);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment