1use super::*;
2
3#[derive(Debug, Clone)]
5pub struct Chain<T> {
6 pub vertices: Vec<vec2<T>>,
8}
9
10impl<T: Float> Chain<T> {
11 pub fn new(vertices: Vec<vec2<T>>) -> Self {
13 Self { vertices }
14 }
15
16 pub fn length(&self) -> T
18 where
19 T: std::iter::Sum<T>,
20 {
21 self.vertices
22 .iter()
23 .zip(self.vertices.iter().skip(1))
24 .map(|(&a, &b)| (a - b).len())
25 .sum()
26 }
27
28 pub fn take_range_ratio(self, range: RangeInclusive<T>) -> Self
38 where
39 T: std::iter::Sum<T>,
40 {
41 let len = self.length();
42 let (start, end) = range.into_inner();
43 self.take_range_length(start * len..=end * len)
44 }
45
46 pub fn take_range_length(self, range: RangeInclusive<T>) -> Self {
56 let &(mut start_len) = range.start();
57 let &(mut end_len) = range.end();
58
59 let segments = self.vertices.iter().zip(self.vertices.iter().skip(1));
60
61 let mut start = self.vertices[0];
62 let mut start_i = 1;
63 for (i, (&a, &b)) in segments.enumerate() {
64 let len = (a - b).len();
65 start_len -= len;
66
67 if start_len < T::ZERO {
68 start = if len.approx_eq(&T::ZERO) {
69 b
70 } else {
71 b + (a - b) * (-start_len / len)
72 };
73 start_i = i + 1;
74 break;
75 }
76
77 end_len -= len;
78 }
79
80 let mut vertices = vec![start];
81
82 for i in start_i..self.vertices.len() {
83 let a = self.vertices[i - 1];
84 let b = self.vertices[i];
85 let len = (a - b).len();
86 end_len -= len;
87
88 if end_len <= T::ZERO {
89 let end = if len.approx_eq(&T::ZERO) {
90 b
91 } else {
92 b + (a - b) * (-end_len / len)
93 };
94 vertices.push(end);
95 break;
96 }
97
98 vertices.push(b);
99 }
100
101 Self { vertices }
102 }
103
104 pub fn segments(&self) -> Vec<Segment<T>> {
106 let length = self.vertices.len();
107 if length < 2 {
108 return vec![];
109 }
110
111 let mut segments = Vec::with_capacity(length - 1);
112 let mut prev = self.vertices[0];
113 for &vertex in self.vertices.iter().skip(1) {
114 segments.push(Segment(prev, vertex));
115 prev = vertex;
116 }
117 segments
118 }
119}