1 use itertools::Itertools; |
1 use itertools::Itertools; |
2 use std::cmp::min; |
2 use std::cmp::min; |
3 |
3 |
4 use integral_geometry::{Line, Point, Rect, Size}; |
4 use integral_geometry::{ |
|
5 Line, Point, Rect, Size, Polygon |
|
6 }; |
5 use land2d::Land2D; |
7 use land2d::Land2D; |
6 |
8 |
7 use outline_template::OutlineTemplate; |
9 use outline_template::OutlineTemplate; |
8 |
10 |
9 pub struct OutlinePoints { |
11 pub struct OutlinePoints { |
10 pub islands: Vec<Vec<Point>>, |
12 pub islands: Vec<Polygon>, |
11 pub fill_points: Vec<Point>, |
13 pub fill_points: Vec<Point>, |
12 pub size: Size, |
14 pub size: Size, |
13 pub play_box: Rect, |
15 pub play_box: Rect, |
14 } |
16 } |
15 |
17 |
35 (rnd_a % rect.width) as i32, |
37 (rnd_a % rect.width) as i32, |
36 (rnd_b % rect.height) as i32, |
38 (rnd_b % rect.height) as i32, |
37 ) |
39 ) |
38 + play_box.top_left() |
40 + play_box.top_left() |
39 }) |
41 }) |
40 .collect() |
42 .collect::<Vec<_>>().into() |
41 }) |
43 }) |
42 .collect(), |
44 .collect(), |
43 fill_points: outline_template.fill_points.clone(), |
45 fill_points: outline_template.fill_points.clone(), |
44 } |
46 } |
45 } |
47 } |
46 |
48 |
47 pub fn total_len(&self) -> usize { |
49 pub fn total_len(&self) -> usize { |
48 self.islands.iter().map(|i| i.len()).sum::<usize>() + self.fill_points.len() |
50 self.islands.iter().map(|i| i.edges_count()).sum::<usize>() + self.fill_points.len() |
49 } |
51 } |
50 |
52 |
51 pub fn iter(&self) -> impl Iterator<Item = &Point> { |
53 pub fn iter(&self) -> impl Iterator<Item = &Point> { |
52 self.islands |
54 self.islands |
53 .iter() |
55 .iter() |
54 .flat_map(|i| i.iter()) |
56 .flat_map(|p| p.iter()) |
55 .chain(self.fill_points.iter()) |
57 .chain(self.fill_points.iter()) |
56 } |
58 } |
57 |
59 |
58 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Point> { |
60 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Point> { |
59 self.islands |
61 self.islands |
233 distance_divisor: u32, |
235 distance_divisor: u32, |
234 random_numbers: &mut I, |
236 random_numbers: &mut I, |
235 ) { |
237 ) { |
236 for is in 0..self.islands.len() { |
238 for is in 0..self.islands.len() { |
237 let mut i = 0; |
239 let mut i = 0; |
238 let mut segment; |
240 while i < self.islands[is].edges_count() { |
239 |
241 let segment = self.islands[is].get_edge(i); |
240 loop { |
242 if let Some(new_point) = self.divide_edge(segment, distance_divisor, random_numbers) { |
241 { |
243 self.islands[is].split_edge(i, new_point); |
242 let island = &self.islands[is]; |
|
243 let mut end_point; |
|
244 if i < island.len() { |
|
245 end_point = if i + 1 < island.len() { |
|
246 island[i + 1] |
|
247 } else { |
|
248 island[0] |
|
249 }; |
|
250 } else { |
|
251 break; |
|
252 } |
|
253 |
|
254 segment = Line::new(island[i], end_point); |
|
255 } |
|
256 |
|
257 if let Some(new_point) = self.divide_edge(segment, distance_divisor, random_numbers) |
|
258 { |
|
259 self.islands[is].insert(i + 1, new_point); |
|
260 i += 2; |
244 i += 2; |
261 } else { |
245 } else { |
262 i += 1; |
246 i += 1; |
263 } |
247 } |
264 } |
248 } |
286 for segment in self.segments_iter() { |
270 for segment in self.segments_iter() { |
287 land.draw_line(segment, value); |
271 land.draw_line(segment, value); |
288 } |
272 } |
289 } |
273 } |
290 |
274 |
291 fn segments_iter(&self) -> OutlineSegmentsIterator { |
275 fn segments_iter<'a>(&'a self) -> impl Iterator<Item = Line> + 'a { |
292 OutlineSegmentsIterator { |
276 self.islands.iter().flat_map(|p| p.iter_edges()) |
293 outline: self, |
|
294 island: 0, |
|
295 index: 0, |
|
296 } |
|
297 } |
277 } |
298 |
278 |
299 pub fn mirror(&mut self) { |
279 pub fn mirror(&mut self) { |
300 let r = self.size.width as i32 - 1; |
280 let r = self.size.width as i32 - 1; |
301 |
281 |
307 |
287 |
308 self.iter_mut().for_each(|p| p.y = t - p.y); |
288 self.iter_mut().for_each(|p| p.y = t - p.y); |
309 } |
289 } |
310 } |
290 } |
311 |
291 |
312 struct OutlineSegmentsIterator<'a> { |
|
313 outline: &'a OutlinePoints, |
|
314 island: usize, |
|
315 index: usize, |
|
316 } |
|
317 |
|
318 impl<'a> Iterator for OutlineSegmentsIterator<'a> { |
|
319 type Item = Line; |
|
320 |
|
321 fn next(&mut self) -> Option<Self::Item> { |
|
322 if self.island < self.outline.islands.len() { |
|
323 if self.index + 1 < self.outline.islands[self.island].len() { |
|
324 let result = Some(Line::new( |
|
325 self.outline.islands[self.island][self.index], |
|
326 self.outline.islands[self.island][self.index + 1], |
|
327 )); |
|
328 |
|
329 self.index += 1; |
|
330 |
|
331 result |
|
332 } else if self.index + 1 == self.outline.islands[self.island].len() { |
|
333 let result = Some(Line::new( |
|
334 self.outline.islands[self.island][self.index], |
|
335 self.outline.islands[self.island][0], |
|
336 )); |
|
337 |
|
338 self.island += 1; |
|
339 self.index = 0; |
|
340 |
|
341 result |
|
342 } else { |
|
343 self.island += 1; |
|
344 self.index = 0; |
|
345 self.next() |
|
346 } |
|
347 } else { |
|
348 None |
|
349 } |
|
350 } |
|
351 } |
|
352 |
|
353 #[test()] |
292 #[test()] |
354 fn points_test() { |
293 fn points_test() { |
|
294 ; |
355 let mut points = OutlinePoints { |
295 let mut points = OutlinePoints { |
|
296 |
356 islands: vec![ |
297 islands: vec![ |
357 vec![Point::new(0, 0), Point::new(20, 0), Point::new(30, 30)], |
298 Polygon::new(&[Point::new(0, 0), Point::new(20, 0), Point::new(30, 30)]), |
358 vec![Point::new(10, 15), Point::new(15, 20), Point::new(20, 15)], |
299 Polygon::new(&[Point::new(10, 15), Point::new(15, 20), Point::new(20, 15)]), |
359 ], |
300 ], |
360 fill_points: vec![Point::new(1, 1)], |
301 fill_points: vec![Point::new(1, 1)], |
361 play_box: Rect::from_box(0, 100, 0, 100).with_margin(10), |
302 play_box: Rect::from_box(0, 100, 0, 100).with_margin(10), |
362 size: Size::square(100), |
303 size: Size::square(100), |
363 }; |
304 }; |
372 Some(&Line::new(Point::new(20, 15), Point::new(10, 15))) |
313 Some(&Line::new(Point::new(20, 15), Point::new(10, 15))) |
373 ); |
314 ); |
374 |
315 |
375 points.iter_mut().for_each(|p| p.x = 2); |
316 points.iter_mut().for_each(|p| p.x = 2); |
376 assert_eq!(points.fill_points[0].x, 2); |
317 assert_eq!(points.fill_points[0].x, 2); |
377 assert_eq!(points.islands[0][0].x, 2); |
318 assert_eq!(points.islands[0].get_edge(0).start.x, 2); |
378 } |
319 } |