1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use crate::{
geometry::Point,
primitives::{
line::{self, Line},
polyline::Polyline,
PointsIter,
},
};
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
#[cfg_attr(feature = "defmt", derive(::defmt::Format))]
pub struct Points<'a> {
vertices: &'a [Point],
translate: Point,
segment_iter: line::Points,
}
impl<'a> Points<'a> {
pub(in crate::primitives) fn new<'b>(polyline: &'b Polyline<'a>) -> Self
where
'a: 'b,
{
polyline
.vertices
.split_first()
.and_then(|(start, rest)| {
rest.get(0).map(|end| Points {
vertices: rest,
translate: polyline.translate,
segment_iter: Line::new(*start + polyline.translate, *end + polyline.translate)
.points(),
})
})
.unwrap_or_else(||
Points {
vertices: &[],
translate: Point::zero(),
segment_iter: line::Points::empty(),
})
}
}
impl<'a> Iterator for Points<'a> {
type Item = Point;
fn next(&mut self) -> Option<Self::Item> {
if let Some(p) = self.segment_iter.next() {
Some(p)
} else {
let (start, rest) = self.vertices.split_first()?;
let end = rest.get(0)?;
self.vertices = rest;
self.segment_iter = Line::new(*start + self.translate, *end + self.translate).points();
self.nth(1)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::primitives::polyline::tests::SMALL;
#[test]
fn no_duplicate_points() {
let expected: [Point; 14] = [
Point::new(2, 5),
Point::new(3, 4),
Point::new(4, 3),
Point::new(5, 2),
Point::new(6, 3),
Point::new(7, 3),
Point::new(8, 4),
Point::new(9, 4),
Point::new(10, 5),
Point::new(11, 4),
Point::new(12, 4),
Point::new(13, 3),
Point::new(14, 3),
Point::new(15, 2),
];
assert!(Polyline::new(&SMALL).points().eq(expected.iter().copied()))
}
#[test]
fn one_point() {
let points = &[Point::zero()];
let polyline = Polyline::new(points);
assert!(polyline.points().eq(core::iter::empty()));
}
#[test]
fn equal_points() {
let points: [Point; 3] = [Point::new(2, 5), Point::new(2, 5), Point::new(2, 5)];
assert!(Polyline::new(&points)
.points()
.eq(core::iter::once(Point::new(2, 5))));
}
}