use crate::scalar::Scalar;
use crate::{point, Box2D, LineSegment, Point, Vector};
use core::ops::Range;
pub trait Segment: Copy + Sized {
type Scalar: Scalar;
fn from(&self) -> Point<Self::Scalar>;
fn to(&self) -> Point<Self::Scalar>;
fn sample(&self, t: Self::Scalar) -> Point<Self::Scalar>;
fn x(&self, t: Self::Scalar) -> Self::Scalar {
self.sample(t).x
}
fn y(&self, t: Self::Scalar) -> Self::Scalar {
self.sample(t).y
}
fn derivative(&self, t: Self::Scalar) -> Vector<Self::Scalar>;
fn dx(&self, t: Self::Scalar) -> Self::Scalar {
self.derivative(t).x
}
fn dy(&self, t: Self::Scalar) -> Self::Scalar {
self.derivative(t).y
}
fn split(&self, t: Self::Scalar) -> (Self, Self);
fn before_split(&self, t: Self::Scalar) -> Self;
fn after_split(&self, t: Self::Scalar) -> Self;
fn split_range(&self, t_range: Range<Self::Scalar>) -> Self;
fn flip(&self) -> Self;
fn approximate_length(&self, tolerance: Self::Scalar) -> Self::Scalar;
fn for_each_flattened_with_t(
&self,
tolerance: Self::Scalar,
callback: &mut dyn FnMut(&LineSegment<Self::Scalar>, Range<Self::Scalar>),
);
}
pub trait BoundingBox {
type Scalar: Scalar;
fn bounding_box(&self) -> Box2D<Self::Scalar> {
let (min_x, max_x) = self.bounding_range_x();
let (min_y, max_y) = self.bounding_range_y();
Box2D {
min: point(min_x, min_y),
max: point(max_x, max_y),
}
}
fn fast_bounding_box(&self) -> Box2D<Self::Scalar> {
let (min_x, max_x) = self.fast_bounding_range_x();
let (min_y, max_y) = self.fast_bounding_range_y();
Box2D {
min: point(min_x, min_y),
max: point(max_x, max_y),
}
}
fn bounding_range_x(&self) -> (Self::Scalar, Self::Scalar);
fn bounding_range_y(&self) -> (Self::Scalar, Self::Scalar);
fn fast_bounding_range_x(&self) -> (Self::Scalar, Self::Scalar);
fn fast_bounding_range_y(&self) -> (Self::Scalar, Self::Scalar);
}
macro_rules! impl_segment {
($S:ty) => {
type Scalar = $S;
fn from(&self) -> Point<$S> {
self.from()
}
fn to(&self) -> Point<$S> {
self.to()
}
fn sample(&self, t: $S) -> Point<$S> {
self.sample(t)
}
fn x(&self, t: $S) -> $S {
self.x(t)
}
fn y(&self, t: $S) -> $S {
self.y(t)
}
fn derivative(&self, t: $S) -> Vector<$S> {
self.derivative(t)
}
fn dx(&self, t: $S) -> $S {
self.dx(t)
}
fn dy(&self, t: $S) -> $S {
self.dy(t)
}
fn split(&self, t: $S) -> (Self, Self) {
self.split(t)
}
fn before_split(&self, t: $S) -> Self {
self.before_split(t)
}
fn after_split(&self, t: $S) -> Self {
self.after_split(t)
}
fn split_range(&self, t_range: Range<$S>) -> Self {
self.split_range(t_range)
}
fn flip(&self) -> Self {
self.flip()
}
fn approximate_length(&self, tolerance: $S) -> $S {
self.approximate_length(tolerance)
}
};
}