prinThor 0.0.3

The highly reliable but not necessarily functional 3D Printer firmware
use core::ops::Div;
use core::ops::Neg;
use crate::math::{HALF, ONE, PI, Real, TWO};
pub trait Interpolator {

    fn interpolate(&self, tp: &Real) -> Real;
}

pub struct LinearInterpolator {
    pub(crate) x0: Real,
    pub(crate) bias: Real,
    pub(crate) slope: Real,
}

pub struct CosineInterpolator {
    pub(crate) x0: Real,
    pub(crate) heigth: Real,
    pub(crate) width: Real,
    pub(crate) bias: Real,
    #[allow(unused)]
    pub(crate) slope: Real,
}

pub struct ExpInterpolator {
    pub(crate) x0: Real,
    pub(crate) heigth: Real,
    pub(crate) width: Real,
    pub(crate) bias: Real,
    #[allow(unused)]
    pub(crate) slope: Real,
}

pub struct UniformInterpolator {
    pub(crate) value: Real,
}

impl Interpolator for UniformInterpolator {
    #[inline]
    fn interpolate(&self, _tp: &Real) -> Real {
        self.value
    }
}

impl Interpolator for LinearInterpolator {
    #[inline]
    fn interpolate(&self, tp: &Real) -> Real {
        self.bias + ((*tp - self.x0) * self.slope)
    }
}

impl Interpolator for CosineInterpolator {
    #[inline]
    fn interpolate(&self, tp: &Real) -> Real {
        self.bias + (self.heigth * (HALF - ((*tp - self.x0).div(self.width) * PI).cos().div(TWO) ))
    }
}

impl Interpolator for ExpInterpolator {
    #[inline]
    fn interpolate(&self, tp: &Real) -> Real {
        let v = (Real::from_f32(12.0) * (*tp- self.x0)/self.width) - Real::from_f32(6.0);
        self.bias + self.heigth * (ONE / (ONE + (v.neg()).exp()))
    }
}