use super::*;
pub struct Trajectory<T> {
function: Box<dyn Fn(T) -> vec2<T>>,
interval: RangeInclusive<T>,
}
impl<T> Trajectory<T> {
pub fn new(function: Box<dyn Fn(T) -> vec2<T>>, interval: RangeInclusive<T>) -> Self {
Self { function, interval }
}
pub fn get(&self, t: T) -> vec2<T> {
(self.function)(t)
}
pub fn parabola(points: [vec2<T>; 3], interval: RangeInclusive<T>) -> Self
where
T: Float + 'static,
{
let [p0, p1, p2] = points;
let c = p1;
let a = (p2 + p0) / T::from_f32(2.0) - c;
let b = (p2 - p0) / T::from_f32(2.0);
Self {
function: Box::new(move |t| a * t * t + b * t + c),
interval,
}
}
}
impl<T> Curve<T> for Trajectory<T> {
fn chain(&self, resolution: usize) -> Chain<T>
where
T: Float,
{
let mut vertices = Vec::with_capacity(resolution);
let start = *self.interval.start();
let end = *self.interval.end();
let step = (end - start) / T::from_f32(resolution as f32);
for i in 0..=resolution {
let t = start + step * T::from_f32(i as f32);
vertices.push(self.get(t));
}
Chain { vertices }
}
}