lineic/lib.rs
1//! # lineic - Flexible linear interpolator for Rust
2//!
3//! [](https://crates.io/crates/lineic/)
4//! [](https://github.com/rscarson/lineic/actions?query=branch%3Amaster)
5//! [](https://docs.rs/lineic/latest/)
6//! [](https://raw.githubusercontent.com/rscarson/lineic/master/LICENSE)
7//!
8//! This library provides a simple way to interpolate between values across a range.
9//! It supports N-dimensional values, mixed types, and interpolation across any number of data sets.
10//!
11//! Inverted ranges work fine, and out of range values are clamped to the provided range.
12//!
13//! The library is designed to be simple to use, and as flexible as possible;
14//! For use with non-standard types, the library provides a `Numeric` trait that can be implemented.
15//!
16//! The library also provides a `no_std` feature for use in embedded systems.
17//! **Warning: The `no_std` feature disables the `LinearInterpolator` struct which enables interpolation across >2 data sets**
18//!
19//! ## Examples
20//!
21//! The simplest possible use of the library is mapping one range to another
22//! Here we can map values in the range `0.0..=10.0` to the range `30.0..=35.0`
23//! ```rust
24//! use lineic::interpolators::F32InterpolationBucket;
25//! let interpolator = F32InterpolationBucket::new(0.0..=10.0, [30.0], [35.0]);
26//! assert_eq!(interpolator.interpolate(5.0), [32.5]);
27//! ```
28//!
29//! `lineic::interpolators::F32InterpolationBucket` here is a type alias for `lineic::InterpolationBucket<1, f32, f32>`
30//! The `interpolators` module defines a set of type aliases for common same-type numeric interpolators.
31//!
32//! -----
33//!
34//! The target does not have to be a single value - here we interpolate across a pair of RGB values
35//! The result is a smooth gradient from `red` to `green` for values in the range `0.0..=10.0`
36//! ```rust
37//! use lineic::interpolators::F32InterpolationBucket;
38//! let interpolator = F32InterpolationBucket::new(0.0..=10.0, [255.0, 0.0, 0.0], [0.0, 255.0, 0.0]);
39//! assert_eq!(interpolator.interpolate(5.0), [127.5, 127.5, 0.0]);
40//! ```
41//!
42//! -----
43//!
44//! The library can also interpolate smoothly across multiple pairs of values
45//! This example forms a sort of traffic light sequence, interpolating between `red`, `yellow`, and `green`
46//!
47//! The range is reversed here to demonstrate that the library can handle that
48//!
49//! ```rust
50//! use lineic::interpolators::F32LinearInterpolator;
51//! ;
52//! let interpolator = F32LinearInterpolator::new(
53//! 10.0..=0.0,
54//! &[[0.0, 255.0, 0.0], [255.0, 255.0, 0.0], [255.0, 0.0, 0.0]],
55//! );
56//! assert_eq!(interpolator.interpolate(5.0), [255.0, 255.0, 0.0]);
57//! assert_eq!(interpolator.interpolate(0.0), [255.0, 0.0, 0.0]);
58//! ```
59//!
60//! -----
61//!
62//! The types for the range and values do not need to the same
63//! Here a `f64` range is used to interpolate across `u8` values
64//! ```rust
65//! use lineic::LinearInterpolator;
66//!
67//! let interpolator: LinearInterpolator<'_, 3, f64, u8> =
68//! LinearInterpolator::new(0.0..=10.0, &[[0, 255, 0], [255, 255, 0], [255, 0, 0]]);
69//!
70//! assert_eq!(interpolator.interpolate(5.0), [255, 255, 0]);
71//! assert_eq!(interpolator.interpolate(0.0), [0, 255, 0]);
72//! ```
73//!
74//! By default, you can interpolate across the following types:
75//! - `f32` `f64`
76//! - `i8` `i16` `i32` `i64` `i128` `isize`
77//! - `u8` `u16` `u32` `u64` `u128` `usize`
78//!
79//! For other types, you can implement the `Numeric` trait.
80//! See `examples/custom_types.rs` for an example of how to do this.
81//!
82#![cfg_attr(feature = "no_std", no_std)]
83#![warn(missing_docs)]
84#![warn(clippy::pedantic)]
85#![allow(clippy::module_name_repetitions)] // Module's are not being exported so they are not being repeated
86
87mod bucket;
88pub use bucket::InterpolationBucket;
89
90mod range;
91pub use range::ReversibleRange;
92
93#[cfg(not(feature = "no_std"))]
94mod interpolator;
95#[cfg(not(feature = "no_std"))]
96pub use interpolator::LinearInterpolator;
97
98mod number;
99pub use number::Numeric;
100
101/// This module contains a set of same-type interpolator type aliases for common numeric types.
102pub mod interpolators {
103 use crate::InterpolationBucket;
104
105 #[cfg(not(feature = "no_std"))]
106 use crate::LinearInterpolator;
107
108 /// Interpolation bucket mapping f64 ranges to f64 values
109 /// For more information, see [`InterpolationBucket`]
110 pub type F64InterpolationBucket<const N: usize> = InterpolationBucket<N, f64, f64>;
111
112 /// Linear interpolator for f64 values
113 /// For more information, see [`LinearInterpolator`]
114 #[cfg(not(feature = "no_std"))]
115 pub type F64LinearInterpolator<'a, const N: usize> = LinearInterpolator<'a, N, f64, f64>;
116
117 /// Interpolation bucket mapping f32 ranges to f32 values
118 /// For more information, see [`InterpolationBucket`]
119 pub type F32InterpolationBucket<const N: usize> = InterpolationBucket<N, f32, f32>;
120
121 /// Linear interpolator for f32 values
122 /// For more information, see [`LinearInterpolator`]
123 #[cfg(not(feature = "no_std"))]
124 pub type F32LinearInterpolator<'a, const N: usize> = LinearInterpolator<'a, N, f32, f32>;
125
126 /// Interpolation bucket mapping i128 ranges to i128 values
127 /// For more information, see [`InterpolationBucket`]
128 pub type I128InterpolationBucket<const N: usize> = InterpolationBucket<N, i128, i128>;
129
130 /// Linear interpolator for i128 values
131 /// For more information, see [`LinearInterpolator`]
132 #[cfg(not(feature = "no_std"))]
133 pub type I128LinearInterpolator<'a, const N: usize> = LinearInterpolator<'a, N, i128, i128>;
134
135 /// Interpolation bucket mapping i64 ranges to i64 values
136 /// For more information, see [`InterpolationBucket`]
137 pub type I64InterpolationBucket<const N: usize> = InterpolationBucket<N, i64, i64>;
138
139 /// Linear interpolator for i64 values
140 /// For more information, see [`LinearInterpolator`]
141 #[cfg(not(feature = "no_std"))]
142 pub type I64LinearInterpolator<'a, const N: usize> = LinearInterpolator<'a, N, i64, i64>;
143
144 /// Interpolation bucket mapping i32 ranges to i32 values
145 /// For more information, see [`InterpolationBucket`]
146 pub type I32InterpolationBucket<const N: usize> = InterpolationBucket<N, i32, i32>;
147
148 /// Linear interpolator for i32 values
149 /// For more information, see [`LinearInterpolator`]
150 #[cfg(not(feature = "no_std"))]
151 pub type I32LinearInterpolator<'a, const N: usize> = LinearInterpolator<'a, N, i32, i32>;
152
153 /// Interpolation bucket mapping i16 ranges to i16 values
154 /// For more information, see [`InterpolationBucket`]
155 pub type I16InterpolationBucket<const N: usize> = InterpolationBucket<N, i16, i16>;
156
157 /// Linear interpolator for i16 values
158 /// For more information, see [`LinearInterpolator`]
159 #[cfg(not(feature = "no_std"))]
160 pub type I16LinearInterpolator<'a, const N: usize> = LinearInterpolator<'a, N, i16, i16>;
161
162 /// Interpolation bucket mapping i8 ranges to i8 values
163 /// For more information, see [`InterpolationBucket`]
164 pub type I8InterpolationBucket<const N: usize> = InterpolationBucket<N, i8, i8>;
165
166 /// Linear interpolator for i8 values
167 /// For more information, see [`LinearInterpolator`]
168 #[cfg(not(feature = "no_std"))]
169 pub type I8LinearInterpolator<'a, const N: usize> = LinearInterpolator<'a, N, i8, i8>;
170
171 /// Interpolation bucket mapping isize ranges to isize values
172 /// For more information, see [`InterpolationBucket`]
173 pub type ISizeInterpolationBucket<const N: usize> = InterpolationBucket<N, isize, isize>;
174
175 /// Linear interpolator for isize values
176 /// For more information, see [`LinearInterpolator`]
177 #[cfg(not(feature = "no_std"))]
178 pub type ISizeLinearInterpolator<'a, const N: usize> = LinearInterpolator<'a, N, isize, isize>;
179
180 /// Interpolation bucket mapping u128 ranges to u128 values
181 /// For more information, see [`InterpolationBucket`]
182 pub type U128InterpolationBucket<const N: usize> = InterpolationBucket<N, u128, u128>;
183
184 /// Linear interpolator for u128 values
185 /// For more information, see [`LinearInterpolator`]
186 #[cfg(not(feature = "no_std"))]
187 pub type U128LinearInterpolator<'a, const N: usize> = LinearInterpolator<'a, N, u128, u128>;
188
189 /// Interpolation bucket mapping u64 ranges to u64 values
190 /// For more information, see [`InterpolationBucket`]
191 pub type U64InterpolationBucket<const N: usize> = InterpolationBucket<N, u64, u64>;
192
193 /// Linear interpolator for u64 values
194 /// For more information, see [`LinearInterpolator`]
195 #[cfg(not(feature = "no_std"))]
196 pub type U64LinearInterpolator<'a, const N: usize> = LinearInterpolator<'a, N, u64, u64>;
197
198 /// Interpolation bucket mapping u32 ranges to u32 values
199 /// For more information, see [`InterpolationBucket`]
200 pub type U32InterpolationBucket<const N: usize> = InterpolationBucket<N, u32, u32>;
201
202 /// Linear interpolator for u32 values
203 /// For more information, see [`LinearInterpolator`]
204 #[cfg(not(feature = "no_std"))]
205 pub type U32LinearInterpolator<'a, const N: usize> = LinearInterpolator<'a, N, u32, u32>;
206
207 /// Interpolation bucket mapping u16 ranges to u16 values
208 /// For more information, see [`InterpolationBucket`]
209 pub type U16InterpolationBucket<const N: usize> = InterpolationBucket<N, u16, u16>;
210
211 /// Linear interpolator for u16 values
212 /// For more information, see [`LinearInterpolator`]
213 #[cfg(not(feature = "no_std"))]
214 pub type U16LinearInterpolator<'a, const N: usize> = LinearInterpolator<'a, N, u16, u16>;
215
216 /// Interpolation bucket mapping u8 ranges to u8 values
217 /// For more information, see [`InterpolationBucket`]
218 pub type U8InterpolationBucket<const N: usize> = InterpolationBucket<N, u8, u8>;
219
220 /// Linear interpolator for u8 values
221 /// For more information, see [`LinearInterpolator`]
222 #[cfg(not(feature = "no_std"))]
223 pub type U8LinearInterpolator<'a, const N: usize> = LinearInterpolator<'a, N, u8, u8>;
224
225 /// Interpolation bucket mapping usize ranges to usize values
226 /// For more information, see [`InterpolationBucket`]
227 pub type USizeInterpolationBucket<const N: usize> = InterpolationBucket<N, usize, usize>;
228
229 /// Linear interpolator for usize values
230 /// For more information, see [`LinearInterpolator`]
231 #[cfg(not(feature = "no_std"))]
232 pub type USizeLinearInterpolator<'a, const N: usize> = LinearInterpolator<'a, N, usize, usize>;
233}