use crate::PathError;
use crate::Point;
use crate::Scalar;
pub trait Path {
type Scalar: Scalar;
type Point: Point<Scalar = Self::Scalar>;
type Error: From<PathError<Self::Scalar>>;
fn length(&self) -> Self::Scalar;
fn sample_at(&self, s: Self::Scalar) -> Result<Self::Point, Self::Error>;
fn start(&self) -> Result<Self::Point, Self::Error> {
self.sample_at(Self::Scalar::zero())
}
fn end(&self) -> Result<Self::Point, Self::Error> {
self.sample_at(self.length())
}
fn domain(&self) -> core::ops::RangeInclusive<Self::Scalar> {
Self::Scalar::zero()..=self.length()
}
}
pub trait ParametricPath: Path {
fn sample_t(&self, t: Self::Scalar) -> Result<Self::Point, Self::Error>;
fn t_to_s(&self, t: Self::Scalar) -> Self::Scalar {
t * self.length()
}
fn s_to_t(&self, s: Self::Scalar) -> Self::Scalar {
s / self.length()
}
}