use crate::easing::smoothstep;
use crate::{Curve, Signal};
use num_traits::FromPrimitive;
use num_traits::real::Real;
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[derive(Debug, Copy, Clone)]
pub struct Plateau<R> {
min: R,
max: R,
}
impl<R> Plateau<R>
where
R: Real + FromPrimitive,
{
pub fn new(strength: R) -> Self {
let halfed = strength / R::from_usize(2).expect("Could not convert 2 into a real number");
Plateau {
min: R::zero() + halfed,
max: R::one() - halfed,
}
}
}
fn over_clamp<R>(input: R, min: R, max: R) -> R
where
R: Real,
{
if input < min {
R::zero()
} else if input > max {
R::one()
} else {
(input - min) / (max - min)
}
}
impl<R> Signal<R> for Plateau<R>
where
R: Real + FromPrimitive,
{
type Output = R;
fn eval(&self, input: R) -> R {
smoothstep(over_clamp(input, self.min, self.max))
}
}
impl<R> Curve<R> for Plateau<R>
where
R: Real + FromPrimitive,
{
fn domain(&self) -> [R; 2] {
[R::zero(), R::one()]
}
}