pub struct LinearInterpolator<'a, const N: usize, S: Numeric, T: Numeric> { /* private fields */ }Expand description
A linear interpolator for a set of values.
Interpolates between a series of discrete value sets based on a range.
For example a traffic light system could be represented as:
use lineic::LinearInterpolator;
const RED: [u8; 3] = [0xB8, 0x1D, 0x13];
const YLW: [u8; 3] = [0xEF, 0xB7, 0x00];
const GRN: [u8; 3] = [0x00, 0x84, 0x50];
let interpolator = LinearInterpolator::new(0.0..=100.0, &[RED, YLW, GRN]);
/*
The result will be a linear interpolation between:
0..=50 => RED->YLW
50..=100 => YLW->GRN
*/§Generics
This type has 3 generics:
- N: The number of values in each set
- S: The numeric type representing the range for inputs
- T: The numeric type representing the values to interpolate between
S and T can be any type implementing the Numeric trait.
Implementations§
Source§impl<'a, const N: usize, S: Numeric, T: Numeric> LinearInterpolator<'a, N, S, T>
impl<'a, const N: usize, S: Numeric, T: Numeric> LinearInterpolator<'a, N, S, T>
Sourcepub fn new(range: impl Into<ReversibleRange<S>>, value_sets: &[[T; N]]) -> Self
pub fn new(range: impl Into<ReversibleRange<S>>, value_sets: &[[T; N]]) -> Self
Create a new linear interpolator with the given range and value sets.
The provided range will be divided into equal segments based on the number of value sets.
§Panics
Panics if the number of value sets is too large to be represented by type S
For a non-panic variant, see Self::try_new
Examples found in repository?
5 6 7 8 9 10 11 12 13 14 15 16 17 18
fn main() {
//
// An interpolator using the NumericUnicode type
let interpolator: LinearInterpolator<1, u8, NumericUnicode> =
LinearInterpolator::new(0..=26, &[['a'.into()], ['z'.into()]]);
//
// Perform an interpolation
let result = interpolator.interpolate(17);
println!(
"The 17th letter of the alphabet is: {:?}",
NumericUnicode::to_string(&result)
);
}More examples
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
fn main() {
// The simplest possible use of the library is mapping one range to another
// Here we can map values in the range 0.0..=10.0 to the range 30.0..=35.0
let interpolator = F32InterpolationBucket::new(0.0..=10.0, [30.0], [35.0]);
assert_eq!(interpolator.interpolate(5.0), [32.5]);
// The target does not have to be a single value - here we interpolate across a pair of RGB values
// The result is a smooth gradient from red to green for values in the range 0.0..=10.0
let interpolator =
F32InterpolationBucket::new(0.0..=10.0, [255.0, 0.0, 0.0], [0.0, 255.0, 0.0]);
assert_eq!(interpolator.interpolate(5.0), [127.5, 127.5, 0.0]);
// The library can also interpolate smoothly across multiple buckets
// This example forms a sort of traffic light sequence, interpolating between red, yellow, and green
// The range is reversed here to demonstrate that the library can handle that
let interpolator = F32LinearInterpolator::new(
10.0..=0.0,
&[[0.0, 255.0, 0.0], [255.0, 255.0, 0.0], [255.0, 0.0, 0.0]],
);
assert_eq!(interpolator.interpolate(5.0), [255.0, 255.0, 0.0]);
assert_eq!(interpolator.interpolate(0.0), [255.0, 0.0, 0.0]);
// The types for the range and values do not need to the same
// Here a f64 range is used to interpolate between u8 values
let interpolator: LinearInterpolator<'_, 3, f64, u8> =
LinearInterpolator::new(0.0..=10.0, &[[0, 255, 0], [255, 255, 0], [255, 0, 0]]);
assert_eq!(interpolator.interpolate(5.0), [127, 127, 0]);
assert_eq!(interpolator.interpolate(0.0), [0, 255, 0]);
}Sourcepub fn try_new(
range: impl Into<ReversibleRange<S>>,
value_sets: &[[T; N]],
) -> Option<Self>
pub fn try_new( range: impl Into<ReversibleRange<S>>, value_sets: &[[T; N]], ) -> Option<Self>
Create a new linear interpolator with the given range and value sets.
The provided range will be divided into equal segments based on the number of value sets.
Returns None if the number of value sets is too large to be represented by type S.
This is the non-panic variant of Self::new
Sourcepub const fn new_from_raw(buckets: &'a [InterpolationBucket<N, S, T>]) -> Self
pub const fn new_from_raw(buckets: &'a [InterpolationBucket<N, S, T>]) -> Self
Create a new linear interpolator from a raw slice of buckets.
Primarily used for static or const interpolators.
Another way to create a const interpolator is with the [static_interpolator!] macro.
§Example
use lineic::{InterpolationBucket, LinearInterpolator};
const INTERPOLATOR: LinearInterpolator<3, f32, f32> = LinearInterpolator::new_from_raw(&[
InterpolationBucket::new_const((0.0, 50.0), [0.0, 0.0, 0.0], [1.0, 1.0, 1.0]),
InterpolationBucket::new_const((50.0, 100.0), [1.0, 1.0, 1.0], [2.0, 2.0, 2.0]),
]);§Safety
Results will be unpredictable if the following are not enforced:
- The range for the buckets must form a continuous range
- The buckets must be sorted by range
Sourcepub fn is_reversed(&self) -> bool
pub fn is_reversed(&self) -> bool
Returns true if the range for this interpolator has start > end
Sourcepub fn buckets(&self) -> &[InterpolationBucket<N, S, T>]
pub fn buckets(&self) -> &[InterpolationBucket<N, S, T>]
Get the set of discrete interpolations this interpolator will use.
Sourcepub fn get_bucket(&self, s: S) -> &InterpolationBucket<N, S, T>
pub fn get_bucket(&self, s: S) -> &InterpolationBucket<N, S, T>
Returns the bucket that contains the given value.
Sourcepub fn interpolate(&self, s: S) -> [T; N]
pub fn interpolate(&self, s: S) -> [T; N]
Interpolate between the value sets based on the given value.
This will return a new set of values interpolated across the given range
Uses a binary search to locate the appropriate pair of values to interpolate between
Examples found in repository?
5 6 7 8 9 10 11 12 13 14 15 16 17 18
fn main() {
//
// An interpolator using the NumericUnicode type
let interpolator: LinearInterpolator<1, u8, NumericUnicode> =
LinearInterpolator::new(0..=26, &[['a'.into()], ['z'.into()]]);
//
// Perform an interpolation
let result = interpolator.interpolate(17);
println!(
"The 17th letter of the alphabet is: {:?}",
NumericUnicode::to_string(&result)
);
}More examples
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
fn main() {
// The simplest possible use of the library is mapping one range to another
// Here we can map values in the range 0.0..=10.0 to the range 30.0..=35.0
let interpolator = F32InterpolationBucket::new(0.0..=10.0, [30.0], [35.0]);
assert_eq!(interpolator.interpolate(5.0), [32.5]);
// The target does not have to be a single value - here we interpolate across a pair of RGB values
// The result is a smooth gradient from red to green for values in the range 0.0..=10.0
let interpolator =
F32InterpolationBucket::new(0.0..=10.0, [255.0, 0.0, 0.0], [0.0, 255.0, 0.0]);
assert_eq!(interpolator.interpolate(5.0), [127.5, 127.5, 0.0]);
// The library can also interpolate smoothly across multiple buckets
// This example forms a sort of traffic light sequence, interpolating between red, yellow, and green
// The range is reversed here to demonstrate that the library can handle that
let interpolator = F32LinearInterpolator::new(
10.0..=0.0,
&[[0.0, 255.0, 0.0], [255.0, 255.0, 0.0], [255.0, 0.0, 0.0]],
);
assert_eq!(interpolator.interpolate(5.0), [255.0, 255.0, 0.0]);
assert_eq!(interpolator.interpolate(0.0), [255.0, 0.0, 0.0]);
// The types for the range and values do not need to the same
// Here a f64 range is used to interpolate between u8 values
let interpolator: LinearInterpolator<'_, 3, f64, u8> =
LinearInterpolator::new(0.0..=10.0, &[[0, 255, 0], [255, 255, 0], [255, 0, 0]]);
assert_eq!(interpolator.interpolate(5.0), [127, 127, 0]);
assert_eq!(interpolator.interpolate(0.0), [0, 255, 0]);
}Sourcepub fn reverse_interpolate(&self, values: &[T; N]) -> Option<S>
pub fn reverse_interpolate(&self, values: &[T; N]) -> Option<S>
Attempt to find a value in the valid range that could produce the given set of values.
This may be slow, since all buckets may be checked
Trait Implementations§
Source§impl<'a, const N: usize, S: Clone + Numeric, T: Clone + Numeric> Clone for LinearInterpolator<'a, N, S, T>
impl<'a, const N: usize, S: Clone + Numeric, T: Clone + Numeric> Clone for LinearInterpolator<'a, N, S, T>
Source§fn clone(&self) -> LinearInterpolator<'a, N, S, T>
fn clone(&self) -> LinearInterpolator<'a, N, S, T>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl<'a, const N: usize, S: Debug + Numeric, T: Debug + Numeric> Debug for LinearInterpolator<'a, N, S, T>
impl<'a, const N: usize, S: Debug + Numeric, T: Debug + Numeric> Debug for LinearInterpolator<'a, N, S, T>
Source§impl<'a, const N: usize, S: PartialEq + Numeric, T: PartialEq + Numeric> PartialEq for LinearInterpolator<'a, N, S, T>
impl<'a, const N: usize, S: PartialEq + Numeric, T: PartialEq + Numeric> PartialEq for LinearInterpolator<'a, N, S, T>
Source§fn eq(&self, other: &LinearInterpolator<'a, N, S, T>) -> bool
fn eq(&self, other: &LinearInterpolator<'a, N, S, T>) -> bool
self and other values to be equal, and is used by ==.