use crate::points::{point2::Point2, point::Point};
#[derive(Debug, Clone, Copy)]
pub struct Bezier {
pub p0: Point2,
pub p1: Point2,
pub p2: Point2,
}
impl Bezier {
pub fn new(p0: Point2, p1: Point2, p2: Point2) -> Self {
Bezier { p0, p1, p2 }
}
pub fn get_point(&self, t: f64) -> Point2 {
let inter_a = self.p0.lerp(self.p1, t);
let inter_b = self.p1.lerp(self.p2, t);
inter_a.lerp(inter_b, t)
}
pub fn get_points(&self, resolution: usize) -> Vec<Point2> {
let mut points = Vec::new();
for i in 0..resolution {
let t = i as f64 / (resolution - 1) as f64;
points.push(self.get_point(t));
}
points
}
pub fn update_points(&self, resolution: usize, points: &mut Vec<Point2>) {
if resolution != points.len() {
*points = Vec::with_capacity(resolution);
}
for i in 0..resolution {
let t = i as f64 / (resolution - 1) as f64;
points.push(self.get_point(t));
}
}
pub fn refresh(&self, points: &mut Vec<Point2>) {
self.update_points(points.len(), points);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_bezier() {
let p0 = Point2::new(0.0, 0.0);
let p1 = Point2::new(1.0, 1.0);
let p2 = Point2::new(2.0, 0.0);
let bezier = Bezier::new(p0, p1, p2);
let points = bezier.get_points(5);
assert_eq!(points.len(), 5);
assert_eq!(points[0], p0);
assert_eq!(points[4], p2);
}
}