traffic_sim/math/
curve.rs

1use super::{Point2d, Vector2d};
2use crate::util::Interval;
3pub use algorithms::*;
4pub use bezier::*;
5
6mod algorithms;
7mod bezier;
8
9/// A parametric curve in 2D space.
10pub trait ParametricCurve2d {
11    /// Samples the parametric curve.
12    fn sample(&self, t: f64) -> Point2d;
13
14    /// Returns the minimum and maximum t-values that define the bounds of the curve.
15    fn bounds(&self) -> Interval<f64>;
16
17    /// Samples the derivative of the parametric curve.
18    ///
19    /// The default implementation approximates the derivative by sampling
20    /// two very nearby points along the curve.
21    fn sample_dt(&self, t: f64) -> Vector2d {
22        let delta = self.bounds().length() * 0.0001;
23        let p1 = self.sample(t);
24        let p2 = self.sample(t + delta);
25        (p2 - p1) / delta
26    }
27
28    /// Samples the second derivative of the parametric curve.
29    ///
30    /// The default implementation approximates the derivative by sampling
31    /// two very nearby points along the curve.
32    fn sample_dt2(&self, t: f64) -> Vector2d {
33        let delta = self.bounds().length() * 0.0001;
34        let p1 = self.sample_dt(t);
35        let p2 = self.sample_dt(t + delta);
36        (p2 - p1) / delta
37    }
38}
39
40impl<T: ParametricCurve2d + ?Sized> ParametricCurve2d for &T {
41    fn sample(&self, t: f64) -> Point2d {
42        (&**self).sample(t)
43    }
44
45    fn bounds(&self) -> Interval<f64> {
46        (&**self).bounds()
47    }
48
49    fn sample_dt(&self, t: f64) -> Vector2d {
50        (&**self).sample_dt(t)
51    }
52
53    fn sample_dt2(&self, t: f64) -> Vector2d {
54        (&**self).sample_dt2(t)
55    }
56}