use crate::poly::Poly; use std::rc::Rc; #[derive(PartialEq, Debug)] pub enum Lerp { Node(Rc, Rc), Leaf(f32, f32), Just(f32), } impl Lerp { pub fn new(v: &Vec) -> Rc { match v.len() { 0 => Rc::new(Lerp::Just(0.0)), 1 => Rc::new(Lerp::Just(v[0])), 2 => Rc::new(Lerp::Leaf(v[0], v[1])), _ => { let mut lv = Vec::new(); for i in 0..v.len() - 1 { lv.push(Rc::new(Lerp::Leaf(v[i], v[i + 1]))); } while lv.len() > 1 { let mut nlv = Vec::new(); for i in 0..lv.len() - 1 { nlv.push(Rc::new(Lerp::Node(lv[i].clone(), lv[i + 1].clone()))); } lv = nlv; } lv[0].clone() } } } pub fn to_poly(&self) -> Poly { match self { Lerp::Just(a) => Poly::new(vec![*a]), Lerp::Leaf(a, b) => Poly::new(vec![*a, *b - *a]), Lerp::Node(a, b) => { let a = a.to_poly(); let b = b.to_poly(); let c = &b - &a; &a + &c.shift() } } } } #[cfg(test)] mod tests { use super::*; #[test] fn new2_test() { let a = Lerp::new(&vec![1.0, 2.0]); assert_eq!(a, Rc::new(Lerp::Leaf(1.0, 2.0))); } #[test] fn new3_test() { let a = Lerp::new(&vec![1.0, 2.0, 3.0]); assert_eq!( a, Rc::new(Lerp::Node( Rc::new(Lerp::Leaf(1.0, 2.0)), Rc::new(Lerp::Leaf(2.0, 3.0)) )) ); } #[test] fn new4_test() { let a = Lerp::new(&vec![1.0, 2.0, 3.0, 4.0]); assert_eq!( a, Rc::new(Lerp::Node( Rc::new(Lerp::Node( Rc::new(Lerp::Leaf(1.0, 2.0)), Rc::new(Lerp::Leaf(2.0, 3.0)) )), Rc::new(Lerp::Node( Rc::new(Lerp::Leaf(2.0, 3.0)), Rc::new(Lerp::Leaf(3.0, 4.0)) )) )) ); } }