diff --git a/CHANGELOG.md b/CHANGELOG.md index 358802f..88910d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +# 3.0.0 + +> Sun Oct 20th 2019 + +## Major changes + +- Sampling now requires the value of the key to be `Linear` for `Interpolate`. That is needed + to ease some interpolation mode (especially Bézier). + +## Patch changes + +- Fix Bézier interpolation when the next key is Bézier too. + # 2.2.0 > Mon Oct 17th 2019 diff --git a/Cargo.toml b/Cargo.toml index 471fbea..787b54c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "splines" -version = "2.2.0" +version = "3.0.0" license = "BSD-3-Clause" authors = ["Dimitri Sabadie "] description = "Spline interpolation made easy" diff --git a/src/interpolate.rs b/src/interpolate.rs index 2f1b3c2..8c79f28 100644 --- a/src/interpolate.rs +++ b/src/interpolate.rs @@ -45,7 +45,7 @@ /// instance to know which trait your type must implement to be usable. /// /// [`Spline::sample`]: crate::spline::Spline::sample -pub trait Interpolate: Sized + Copy { +pub trait Interpolate: Sized + Copy + Linear { /// Linear interpolation. fn lerp(a: Self, b: Self, t: T) -> Self; @@ -240,10 +240,7 @@ where V: Linear, let one_t_3 = one_t_2 * one_t; let three = T::one() + T::one() + T::one(); - // mirror the “output” tangent based on the next key “input” tangent - let v_ = b + b - v; - - a.outer_mul(one_t_3) + u.outer_mul(three * one_t_2 * t) + v_.outer_mul(three * one_t * t * t) + b.outer_mul(t * t * t) + a.outer_mul(one_t_3) + u.outer_mul(three * one_t_2 * t) + v.outer_mul(three * one_t * t * t) + b.outer_mul(t * t * t) } macro_rules! impl_interpolate_simple { diff --git a/src/spline.rs b/src/spline.rs index 2051dea..b12b4a1 100644 --- a/src/spline.rs +++ b/src/spline.rs @@ -7,7 +7,7 @@ #[cfg(not(feature = "std"))] use core::ops::{Div, Mul}; #[cfg(not(feature = "std"))] use core::cmp::Ordering; -use crate::interpolate::{Interpolate, Additive, One, Trigo}; +use crate::interpolate::{Additive, Interpolate, One, Trigo}; use crate::interpolation::Interpolation; use crate::key::Key; @@ -86,7 +86,7 @@ impl Spline { /// the sampling. pub fn sample_with_key(&self, t: T) -> Option<(V, &Key, Option<&Key>)> where T: Additive + One + Trigo + Mul + Div + PartialOrd, - V: Interpolate { + V: Additive + Interpolate { let keys = &self.0; let i = search_lower_cp(keys, t)?; let cp0 = &keys[i]; @@ -134,29 +134,27 @@ impl Spline { } } - Interpolation::Bezier(u) => { + Interpolation::Bezier(u) | Interpolation::StrokeBezier(_, u) => { // We need to check the next control point to see whether we want quadratic or cubic Bezier. let cp1 = &keys[i + 1]; let nt = normalize_time(t, cp0, cp1); let value = - if let Interpolation::Bezier(v) = cp1.interpolation { - Interpolate::cubic_bezier(cp0.value, u, v, cp1.value, nt) - } else { - Interpolate::quadratic_bezier(cp0.value, u, cp1.value, nt) + match cp1.interpolation { + Interpolation::Bezier(v) => { + Interpolate::cubic_bezier(cp0.value, u, cp1.value + cp1.value - v, cp1.value, nt) + } + + Interpolation::StrokeBezier(v, _) => { + Interpolate::cubic_bezier(cp0.value, u, v, cp1.value, nt) + } + + _ => Interpolate::quadratic_bezier(cp0.value, u, cp1.value, nt) }; Some((value, cp0, Some(cp1))) } - Interpolation::StrokeBezier(input, output) => { - let cp1 = &keys[i + 1]; - let nt = normalize_time(t, cp0, cp1); - let value = Interpolate::cubic_bezier(cp0.value, input, output, cp1.value, nt); - - Some((value, cp0, Some(cp1))) - } - Interpolation::__NonExhaustive => unreachable!(), } }