Interpolation made easy.
Go to file
Dimitri Sabadie f04ea0fefa
Revert "Merge pull request #39 from alexbool/update-nalgebra-0.20"
This reverts commit 8ceb8d768c, reversing
changes made to d80de42d2f.
2020-03-16 16:43:20 +01:00
.github/workflows Add Interpolation::StrokeBezier. 2019-10-17 17:23:46 +02:00
examples Fix examples. 2019-10-22 13:34:11 +02:00
src Fix Bézier interpolation. 2019-10-22 20:23:36 +02:00
tests Update integration tests for stroke Bézier. 2019-10-22 20:59:46 +02:00
.gitignore Add all target/ build dir to the .gitignore. 2018-08-07 01:28:45 +02:00
Cargo.toml Revert "Merge pull request #39 from alexbool/update-nalgebra-0.20" 2020-03-16 16:43:20 +01:00
CHANGELOG.md Prepare 3.1.0. 2020-01-26 21:19:25 +01:00
LICENSE Add missing LICENSE file. 2019-10-17 01:45:53 +02:00
README.md 2.0.0. 2019-09-24 10:42:03 +02:00

This crate provides splines, mathematic curves defined piecewise through control keys a.k.a. knots.

Feel free to dig in the online documentation for further information.

Spline interpolation made easy.

This crate exposes splines for which each sections can be interpolated independently of each other i.e. its possible to interpolate with a linear interpolator on one section and then switch to a cubic Hermite interpolator for the next section.

Most of the crate consists of three types:

  • [Key], which represents the control points by which the spline must pass.
  • Interpolation, the type of possible interpolation for each segment.
  • [Spline], a spline from which you can sample points by interpolation.

When adding control points, you add new sections. Two control points define a section i.e. its not possible to define a spline without at least two control points. Every time you add a new control point, a new section is created. Each section is assigned an interpolation mode that is picked from its lower control point.

Quickly create splines

use splines::{Interpolation, Key, Spline};

let start = Key::new(0., 0., Interpolation::Linear);
let end = Key::new(1., 10., Interpolation::default());
let spline = Spline::from_vec(vec![start, end]);

You will notice that we used Interpolation::Linear for the first key. The first key starts interpolation will be used for the whole segment defined by those two keys. The ends interpolation wont be used. You can in theory use any Interpolation you want for the last key. We use the default one because we dont care.

Interpolate values

The whole purpose of splines is to interpolate discrete values to yield continuous ones. This is usually done with the [Spline::sample] method. This method expects the sampling parameter (often, this will be the time of your simulation) as argument and will yield an interpolated value.

If you try to sample in out-of-bounds sampling parameter, youll get no value.

assert_eq!(spline.sample(0.), Some(0.));
assert_eq!(spline.clamped_sample(1.), Some(10.));
assert_eq!(spline.sample(1.1), None);

Its possible that you want to get a value even if youre out-of-bounds. This is especially important for simulations / animations. Feel free to use the Spline::clamped_interpolation for that purpose.

assert_eq!(spline.clamped_sample(-0.9), Some(0.)); // clamped to the first key
assert_eq!(spline.clamped_sample(1.1), Some(10.)); // clamped to the last key

Polymorphic sampling types

[Spline] curves are parametered both by the carried value (being interpolated) but also the sampling type. Its very typical to use f32 or f64 but really, you can in theory use any kind of type; that type must, however, implement a contract defined by a set of traits to implement. See the documentation of this module for further details.

Features and customization

This crate was written with features baked in and hidden behind feature-gates. The idea is that the default configuration (i.e. you just add "splines = …" to your Cargo.toml) will always give you the minimal, core and raw concepts of what splines, keys / knots and interpolation modes are. However, you might want more. Instead of letting other people do the extra work to add implementations for very famous and useful traits and do it in less efficient way, because they wouldnt have access to the internals of this crate, its possible to enable features in an ad hoc way.

This mechanism is not final and this is currently an experiment to see how people like it or not. Its especially important to see how it copes with the documentation.

So heres a list of currently supported features and how to enable them:

  • Serialization / deserialization.
    • This feature implements both the Serialize and Deserialize traits from serde for all types exported by this crate.
    • Enable with the "serialization" feature.
  • cgmath implementors.
    • Adds some useful implementations of Interpolate for some cgmath types.
    • Enable with the "impl-cgmath" feature.
  • nalgebra implementors.
    • Adds some useful implementations of Interpolate for some nalgebra types.
    • Enable with the "impl-nalgebra" feature.
  • Standard library / no standard library.
    • Its possible to compile against the standard library or go on your own without it.
    • Compiling with the standard library is enabled by default.
    • Use default-features = [] in your Cargo.toml to disable.
    • Enable explicitly with the "std" feature.