1use crate::scalar::Scalar;
2use crate::{LineSegment, Point, Vector};
3
4use core::ops::Range;
5
6pub trait Segment: Copy + Sized {
8 type Scalar: Scalar;
9
10 fn from(&self) -> Point<Self::Scalar>;
12
13 fn to(&self) -> Point<Self::Scalar>;
15
16 fn sample(&self, t: Self::Scalar) -> Point<Self::Scalar>;
18
19 fn x(&self, t: Self::Scalar) -> Self::Scalar {
21 self.sample(t).x
22 }
23
24 fn y(&self, t: Self::Scalar) -> Self::Scalar {
26 self.sample(t).y
27 }
28
29 fn derivative(&self, t: Self::Scalar) -> Vector<Self::Scalar>;
31
32 fn dx(&self, t: Self::Scalar) -> Self::Scalar {
34 self.derivative(t).x
35 }
36
37 fn dy(&self, t: Self::Scalar) -> Self::Scalar {
39 self.derivative(t).y
40 }
41
42 fn split(&self, t: Self::Scalar) -> (Self, Self);
44
45 fn before_split(&self, t: Self::Scalar) -> Self;
47
48 fn after_split(&self, t: Self::Scalar) -> Self;
50
51 fn split_range(&self, t_range: Range<Self::Scalar>) -> Self;
55
56 fn flip(&self) -> Self;
58
59 fn approximate_length(&self, tolerance: Self::Scalar) -> Self::Scalar;
61
62 #[allow(clippy::type_complexity)]
69 fn for_each_flattened_with_t(
70 &self,
71 tolerance: Self::Scalar,
72 callback: &mut dyn FnMut(&LineSegment<Self::Scalar>, Range<Self::Scalar>),
73 );
74}
75
76macro_rules! impl_segment {
77 ($S:ty) => {
78 type Scalar = $S;
79 fn from(&self) -> Point<$S> {
80 self.from()
81 }
82 fn to(&self) -> Point<$S> {
83 self.to()
84 }
85 fn sample(&self, t: $S) -> Point<$S> {
86 self.sample(t)
87 }
88 fn x(&self, t: $S) -> $S {
89 self.x(t)
90 }
91 fn y(&self, t: $S) -> $S {
92 self.y(t)
93 }
94 fn derivative(&self, t: $S) -> Vector<$S> {
95 self.derivative(t)
96 }
97 fn dx(&self, t: $S) -> $S {
98 self.dx(t)
99 }
100 fn dy(&self, t: $S) -> $S {
101 self.dy(t)
102 }
103 fn split(&self, t: $S) -> (Self, Self) {
104 self.split(t)
105 }
106 fn before_split(&self, t: $S) -> Self {
107 self.before_split(t)
108 }
109 fn after_split(&self, t: $S) -> Self {
110 self.after_split(t)
111 }
112 fn split_range(&self, t_range: Range<$S>) -> Self {
113 self.split_range(t_range)
114 }
115 fn flip(&self) -> Self {
116 self.flip()
117 }
118 fn approximate_length(&self, tolerance: $S) -> $S {
119 self.approximate_length(tolerance)
120 }
121 };
122}