diff --git a/src/spline.rs b/src/spline.rs index c7b7749..5a6c4db 100644 --- a/src/spline.rs +++ b/src/spline.rs @@ -28,12 +28,17 @@ use crate::key::Key; pub struct Spline(pub(crate) Vec>); impl Spline { + /// Internal sort to ensure invariant of sorting keys is valid. + fn internal_sort(&mut self) where T: PartialOrd { + self.0.sort_by(|k0, k1| k0.t.partial_cmp(&k1.t).unwrap_or(Ordering::Less)); + } + /// Create a new spline out of keys. The keys don’t have to be sorted even though it’s recommended /// to provide ascending sorted ones (for performance purposes). - pub fn from_vec(mut keys: Vec>) -> Self where T: PartialOrd { - keys.sort_by(|k0, k1| k0.t.partial_cmp(&k1.t).unwrap_or(Ordering::Less)); - - Spline(keys) + pub fn from_vec(keys: Vec>) -> Self where T: PartialOrd { + let mut spline = Spline(keys); + spline.internal_sort(); + spline } /// Create a new spline by consuming an `Iterater>`. They keys don’t have to be @@ -159,6 +164,12 @@ impl Spline { }) } + /// Add a key into the spline. + pub fn add(&mut self, key: Key) where T: PartialOrd { + self.0.push(key); + self.internal_sort(); + } + /// Remove a key from the spline. pub fn remove(&mut self, index: usize) -> Option> { if index >= self.0.len() { diff --git a/tests/mod.rs b/tests/mod.rs index f66f383..fbbdcff 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -173,6 +173,30 @@ fn nalgebra_vector_interpolation() { assert_eq!(Interpolate::lerp(start, end, 0.5), mid); } +#[test] +fn add_key_empty() { + let mut spline: Spline = Spline::from_vec(vec![]); + spline.add(Key::new(0., 0., Interpolation::Linear)); + + assert_eq!(spline.keys(), &[Key::new(0., 0., Interpolation::Linear)]); +} + +#[test] +fn add_key() { + let start = Key::new(0., 0., Interpolation::Step(0.5)); + let k1 = Key::new(1., 5., Interpolation::Linear); + let k2 = Key::new(2., 0., Interpolation::Step(0.1)); + let k3 = Key::new(3., 1., Interpolation::Linear); + let k4 = Key::new(10., 2., Interpolation::Linear); + let end = Key::new(11., 4., Interpolation::default()); + let new = Key::new(2.4, 40., Interpolation::Linear); + let mut spline = Spline::from_vec(vec![start, k1, k2.clone(), k3, k4, end]); + + assert_eq!(spline.keys(), &[start, k1, k2, k3, k4, end]); + spline.add(new); + assert_eq!(spline.keys(), &[start, k1, k2, new, k3, k4, end]); +} + #[test] fn remove_element_empty() { let mut spline: Spline = Spline::from_vec(vec![]);