1 use itertools::Itertools; |
1 use itertools::Itertools; |
2 |
2 |
3 use integral_geometry::{Line, Point, Size}; |
3 use integral_geometry::{Line, Point, Rect, Size}; |
4 use land2d::Land2D; |
4 use land2d::Land2D; |
5 |
5 |
6 use outline_template::OutlineTemplate; |
6 use outline_template::OutlineTemplate; |
7 |
7 |
8 pub struct OutlinePoints { |
8 pub struct OutlinePoints { |
9 pub islands: Vec<Vec<Point>>, |
9 pub islands: Vec<Vec<Point>>, |
10 pub fill_points: Vec<Point>, |
10 pub fill_points: Vec<Point>, |
11 pub size: Size, |
11 pub size: Size, |
|
12 pub play_box: Rect, |
12 } |
13 } |
13 |
14 |
14 impl OutlinePoints { |
15 impl OutlinePoints { |
15 pub fn from_outline_template<I: Iterator<Item = u32>>( |
16 pub fn from_outline_template<I: Iterator<Item = u32>>( |
16 outline_template: &OutlineTemplate, |
17 outline_template: &OutlineTemplate, |
|
18 play_box: Rect, |
|
19 size: Size, |
17 random_numbers: &mut I, |
20 random_numbers: &mut I, |
18 ) -> Self { |
21 ) -> Self { |
19 Self { |
22 Self { |
|
23 play_box, |
|
24 size, |
20 islands: outline_template |
25 islands: outline_template |
21 .islands |
26 .islands |
22 .iter() |
27 .iter() |
23 .map(|i| { |
28 .map(|i| { |
24 i.iter() |
29 i.iter() |
25 .zip(random_numbers.tuples()) |
30 .zip(random_numbers.tuples()) |
26 .map(|(rect, (rnd_a, rnd_b))| { |
31 .map(|(rect, (rnd_a, rnd_b))| { |
27 Point::new( |
32 rect.top_left() |
28 rect.x + (rnd_a % rect.width) as i32, |
33 + Point::new( |
29 rect.y + (rnd_b % rect.height) as i32, |
34 (rnd_a % rect.width) as i32, |
30 ) |
35 (rnd_b % rect.height) as i32, |
|
36 ) |
|
37 + play_box.top_left() |
31 }).collect() |
38 }).collect() |
32 }).collect(), |
39 }).collect(), |
33 fill_points: outline_template.fill_points.clone(), |
40 fill_points: outline_template.fill_points.clone(), |
34 size: outline_template.size, |
|
35 } |
41 } |
36 } |
42 } |
37 |
43 |
38 pub fn total_len(&self) -> usize { |
44 pub fn total_len(&self) -> usize { |
39 self.islands.iter().map(|i| i.len()).sum::<usize>() + self.fill_points.len() |
45 self.islands.iter().map(|i| i.len()).sum::<usize>() + self.fill_points.len() |
49 fn divide_edge<I: Iterator<Item = u32>>( |
55 fn divide_edge<I: Iterator<Item = u32>>( |
50 &self, |
56 &self, |
51 segment: Line, |
57 segment: Line, |
52 random_numbers: &mut I, |
58 random_numbers: &mut I, |
53 ) -> Option<Point> { |
59 ) -> Option<Point> { |
54 |
|
55 None |
60 None |
56 } |
61 } |
57 |
62 |
58 fn divide_edges<I: Iterator<Item = u32>>(&mut self, random_numbers: &mut I) { |
63 fn divide_edges<I: Iterator<Item = u32>>(&mut self, random_numbers: &mut I) { |
59 for is in 0..self.islands.len() { |
64 for is in 0..self.islands.len() { |
128 impl<'a> Iterator for OutlineSegmentsIterator<'a> { |
133 impl<'a> Iterator for OutlineSegmentsIterator<'a> { |
129 type Item = Line; |
134 type Item = Line; |
130 |
135 |
131 fn next(&mut self) -> Option<Self::Item> { |
136 fn next(&mut self) -> Option<Self::Item> { |
132 if self.island < self.outline.islands.len() { |
137 if self.island < self.outline.islands.len() { |
133 if self.index + 1 < self.outline.islands[self.index].len() { |
138 if self.index + 1 < self.outline.islands[self.island].len() { |
134 Some(Line::new( |
139 let result = Some(Line::new( |
135 self.outline.islands[self.index][self.index], |
140 self.outline.islands[self.island][self.index], |
136 self.outline.islands[self.index][self.index + 1], |
141 self.outline.islands[self.island][self.index + 1], |
137 )) |
142 )); |
138 } else if self.index + 1 == self.outline.islands[self.index].len() { |
143 |
139 Some(Line::new( |
144 self.index += 1; |
140 self.outline.islands[self.index][self.index], |
145 |
141 self.outline.islands[self.index][0], |
146 result |
142 )) |
147 } else if self.index + 1 == self.outline.islands[self.island].len() { |
|
148 let result = Some(Line::new( |
|
149 self.outline.islands[self.island][self.index], |
|
150 self.outline.islands[self.island][0], |
|
151 )); |
|
152 |
|
153 self.island += 1; |
|
154 self.index = 0; |
|
155 |
|
156 result |
143 } else { |
157 } else { |
144 self.island += 1; |
158 self.island += 1; |
|
159 self.index = 0; |
145 self.next() |
160 self.next() |
146 } |
161 } |
147 } else { |
162 } else { |
148 None |
163 None |
149 } |
164 } |
150 } |
165 } |
151 } |
166 } |
|
167 |
|
168 #[test()] |
|
169 fn points_test() { |
|
170 let mut points = OutlinePoints { |
|
171 islands: vec![ |
|
172 vec![Point::new(0, 0), Point::new(20, 0), Point::new(30, 30)], |
|
173 vec![Point::new(10, 15), Point::new(15, 20), Point::new(20, 15)], |
|
174 ], |
|
175 fill_points: vec![Point::new(1, 1)], |
|
176 play_box: Rect::from_box(0, 100, 0, 100).with_margin(10), |
|
177 size: Size::square(100), |
|
178 }; |
|
179 |
|
180 let segments: Vec<Line> = points.segments_iter().collect(); |
|
181 assert_eq!( |
|
182 segments.first(), |
|
183 Some(&Line::new(Point::new(0, 0), Point::new(20, 0))) |
|
184 ); |
|
185 assert_eq!( |
|
186 segments.last(), |
|
187 Some(&Line::new(Point::new(20, 15), Point::new(10, 15))) |
|
188 ); |
|
189 |
|
190 points.iter_mut().for_each(|p| p.x = 2); |
|
191 assert_eq!(points.fill_points[0].x, 2); |
|
192 assert_eq!(points.islands[0][0].x, 2); |
|
193 } |