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
113
114
115
116
117
118
119
120
121
122
123
124
use crate::{
Angle, Canvas, Center, Ellipse, FlatIterPath, Paint, Rect, Rotate, Scale, Subdivide, Translate,
P2, V2,
};
use arrayvec::ArrayVec;
use itertools::Itertools;
use std::iter::{DoubleEndedIterator, FromIterator};
#[derive(Debug, Clone, PartialEq)]
pub struct Polygon {
vertices: Vec<P2>,
}
impl Polygon {
pub fn vertices<'a>(&'a self) -> impl DoubleEndedIterator<Item = P2> + Clone + 'a {
self.vertices.iter().copied()
}
pub fn vertices_mut<'a>(&'a mut self) -> impl DoubleEndedIterator<Item = &'a mut P2> + 'a {
self.vertices.iter_mut()
}
pub fn vertices_with_neighbors<'a>(&'a self) -> impl Iterator<Item = (P2, P2, P2)> + 'a {
let last_iter = self.vertices().rev().take(1);
last_iter
.clone()
.chain(self.vertices())
.chain(last_iter)
.tuple_windows()
}
}
impl Paint for Polygon {
fn paint(&self, canvas: &mut Canvas) {
canvas.paint(FlatIterPath::new(self.vertices(), true))
}
}
impl Paint for &Polygon {
fn paint(&self, canvas: &mut Canvas) {
(**self).paint(canvas);
}
}
impl Subdivide for Polygon {
fn subdivide(self) -> Self {
let from_start = self.vertices();
let skipped = self.vertices().skip(1).chain(self.vertices().take(1));
from_start
.zip(skipped)
.flat_map(|(a, b)| {
let midpoint = a + ((b + (a.to_vector() * -1.)) * 0.5).to_vector();
ArrayVec::from([a, midpoint]).into_iter()
})
.collect::<Self>()
}
}
impl Rotate for Polygon {
fn rotate(mut self, pivot: P2, theta: Angle) -> Self {
self.vertices_mut().for_each(|v| {
*v = v.rotate(pivot, theta);
});
self
}
}
impl Translate for Polygon {
fn translate(mut self, translation: V2) -> Self {
self.vertices.iter_mut().for_each(|p| *p += translation);
self
}
}
impl Center for Polygon {
fn center(&self) -> P2 {
Rect::extent(self.vertices()).center()
}
}
impl Scale for Polygon {
fn scale(mut self, factor: f32) -> Self {
let scale_vertex_from = |anchor: P2, v: P2| -> P2 {
let distance = (anchor - v).length();
let phase = Ellipse::circle(anchor, distance).circumphase(&v);
Ellipse::circle(anchor, distance * factor).circumpoint(phase)
};
let center = self.center();
self.vertices
.iter_mut()
.for_each(|p| *p = scale_vertex_from(center, *p));
self
}
}
impl<I> From<I> for Polygon
where
I: Iterator<Item = P2>,
{
fn from(src: I) -> Self {
Self {
vertices: src.collect(),
}
}
}
impl FromIterator<P2> for Polygon {
fn from_iter<T>(iter: T) -> Self
where
T: IntoIterator<Item = P2>,
{
Self {
vertices: iter.into_iter().collect(),
}
}
}