lyon_geom/
segment.rs

1use crate::scalar::Scalar;
2use crate::{LineSegment, Point, Vector};
3
4use core::ops::Range;
5
6/// Common APIs to segment types.
7pub trait Segment: Copy + Sized {
8    type Scalar: Scalar;
9
10    /// Start of the curve.
11    fn from(&self) -> Point<Self::Scalar>;
12
13    /// End of the curve.
14    fn to(&self) -> Point<Self::Scalar>;
15
16    /// Sample the curve at t (expecting t between 0 and 1).
17    fn sample(&self, t: Self::Scalar) -> Point<Self::Scalar>;
18
19    /// Sample x at t (expecting t between 0 and 1).
20    fn x(&self, t: Self::Scalar) -> Self::Scalar {
21        self.sample(t).x
22    }
23
24    /// Sample y at t (expecting t between 0 and 1).
25    fn y(&self, t: Self::Scalar) -> Self::Scalar {
26        self.sample(t).y
27    }
28
29    /// Sample the derivative at t (expecting t between 0 and 1).
30    fn derivative(&self, t: Self::Scalar) -> Vector<Self::Scalar>;
31
32    /// Sample x derivative at t (expecting t between 0 and 1).
33    fn dx(&self, t: Self::Scalar) -> Self::Scalar {
34        self.derivative(t).x
35    }
36
37    /// Sample y derivative at t (expecting t between 0 and 1).
38    fn dy(&self, t: Self::Scalar) -> Self::Scalar {
39        self.derivative(t).y
40    }
41
42    /// Split this curve into two sub-curves.
43    fn split(&self, t: Self::Scalar) -> (Self, Self);
44
45    /// Return the curve before the split point.
46    fn before_split(&self, t: Self::Scalar) -> Self;
47
48    /// Return the curve after the split point.
49    fn after_split(&self, t: Self::Scalar) -> Self;
50
51    /// Return the curve inside a given range of t.
52    ///
53    /// This is equivalent splitting at the range's end points.
54    fn split_range(&self, t_range: Range<Self::Scalar>) -> Self;
55
56    /// Swap the direction of the segment.
57    fn flip(&self) -> Self;
58
59    /// Compute the length of the segment using a flattened approximation.
60    fn approximate_length(&self, tolerance: Self::Scalar) -> Self::Scalar;
61
62    /// Approximates the curve with sequence of line segments.
63    ///
64    /// The `tolerance` parameter defines the maximum distance between the curve and
65    /// its approximation.
66    ///
67    /// The parameter `t` at the final segment is guaranteed to be equal to `1.0`.
68    #[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}