amagi 0.1.4

Rust SDK, CLI, and Web API service skeleton for multi-platform social web adapters.
Documentation
#[derive(Debug, Clone)]
pub(super) struct Cubic {
    curves: Vec<f64>,
}

impl Cubic {
    pub(super) fn new(curves: Vec<f64>) -> Self {
        Self { curves }
    }

    pub(super) fn get_value(&self, time: f64) -> f64 {
        let mut start_gradient = 0.0;
        let mut end_gradient = 0.0;
        let mut start = 0.0;
        let mut mid = 0.0;
        let mut end = 1.0;

        if time <= 0.0 {
            if self.curves[0] > 0.0 {
                start_gradient = self.curves[1] / self.curves[0];
            } else if self.curves[1] == 0.0 && self.curves[2] > 0.0 {
                start_gradient = self.curves[3] / self.curves[2];
            }
            return start_gradient * time;
        }

        if time >= 1.0 {
            if self.curves[2] < 1.0 {
                end_gradient = (self.curves[3] - 1.0) / (self.curves[2] - 1.0);
            } else if self.curves[2] == 1.0 && self.curves[0] < 1.0 {
                end_gradient = (self.curves[1] - 1.0) / (self.curves[0] - 1.0);
            }
            return 1.0 + end_gradient * (time - 1.0);
        }

        for _ in 0..64 {
            mid = (start + end) / 2.0;
            let x_est = Self::calculate(self.curves[0], self.curves[2], mid);
            if (time - x_est).abs() < 0.00001 {
                return Self::calculate(self.curves[1], self.curves[3], mid);
            }
            if x_est < time {
                start = mid;
            } else {
                end = mid;
            }
        }

        Self::calculate(self.curves[1], self.curves[3], mid)
    }

    fn calculate(a: f64, b: f64, m: f64) -> f64 {
        3.0 * a * (1.0 - m) * (1.0 - m) * m + 3.0 * b * (1.0 - m) * m * m + m * m * m
    }
}