|
1 use itertools::Itertools; |
|
2 |
|
3 use integral_geometry::{Point, Size}; |
|
4 use land2d::Land2D; |
|
5 |
|
6 use outline_template::OutlineTemplate; |
|
7 |
|
8 pub struct OutlinePoints { |
|
9 pub islands: Vec<Vec<Point>>, |
|
10 pub fill_points: Vec<Point>, |
|
11 pub size: Size, |
|
12 } |
|
13 |
|
14 impl OutlinePoints { |
|
15 pub fn from_outline_template<I: Iterator<Item = u32>>( |
|
16 outline_template: &OutlineTemplate, |
|
17 random_numbers: &mut I, |
|
18 ) -> Self { |
|
19 Self { |
|
20 islands: outline_template |
|
21 .islands |
|
22 .iter() |
|
23 .map(|i| { |
|
24 i.iter() |
|
25 .zip(random_numbers.tuples()) |
|
26 .map(|(rect, (rnd_a, rnd_b))| { |
|
27 Point::new( |
|
28 rect.x + (rnd_a % rect.width) as i32, |
|
29 rect.y + (rnd_b % rect.height) as i32, |
|
30 ) |
|
31 }).collect() |
|
32 }).collect(), |
|
33 fill_points: outline_template.fill_points.clone(), |
|
34 size: outline_template.size, |
|
35 } |
|
36 } |
|
37 |
|
38 pub fn total_len(&self) -> usize { |
|
39 self.islands.iter().map(|i| i.len()).sum::<usize>() + self.fill_points.len() |
|
40 } |
|
41 |
|
42 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Point> { |
|
43 self.islands |
|
44 .iter_mut() |
|
45 .flat_map(|i| i.iter_mut()) |
|
46 .chain(self.fill_points.iter_mut()) |
|
47 } |
|
48 |
|
49 fn divide_edge<I: Iterator<Item = u32>>( |
|
50 &self, |
|
51 start_point: Point, |
|
52 end_point: Point, |
|
53 random_numbers: &mut I, |
|
54 ) -> Option<Point> { |
|
55 None |
|
56 } |
|
57 |
|
58 fn divide_edges<I: Iterator<Item = u32>>(&mut self, random_numbers: &mut I) { |
|
59 for is in 0..self.islands.len() { |
|
60 let mut i = 0; |
|
61 let mut start_point = Point::zero(); |
|
62 let mut end_point = Point::zero(); |
|
63 |
|
64 loop { |
|
65 { |
|
66 let island = &self.islands[is]; |
|
67 if i < island.len() { |
|
68 start_point = island[i]; |
|
69 end_point = if i + 1 < island.len() { |
|
70 island[i + 1] |
|
71 } else { |
|
72 island[0] |
|
73 }; |
|
74 } else { |
|
75 break |
|
76 } |
|
77 } |
|
78 |
|
79 if let Some(new_point) = self.divide_edge(start_point, end_point, random_numbers) { |
|
80 self.islands[is].insert(i + 1, new_point); |
|
81 i += 2; |
|
82 } else { |
|
83 i += 1; |
|
84 } |
|
85 } |
|
86 } |
|
87 } |
|
88 |
|
89 pub fn bezierize(&mut self) { |
|
90 unimplemented!() |
|
91 } |
|
92 |
|
93 pub fn distort<I: Iterator<Item = u32>>(&mut self, random_numbers: &mut I) { |
|
94 loop { |
|
95 let old_len = self.total_len(); |
|
96 self.divide_edges(random_numbers); |
|
97 |
|
98 if self.total_len() != old_len { |
|
99 break; |
|
100 } |
|
101 } |
|
102 |
|
103 self.bezierize(); |
|
104 } |
|
105 |
|
106 pub fn draw<T: Copy + PartialEq>(&self, land: &mut Land2D<T>, value: T) { |
|
107 for island in &self.islands { |
|
108 if island.len() > 1 { |
|
109 for i in 0..island.len() - 1 { |
|
110 land.draw_line(island[i], island[i + 1], value); |
|
111 } |
|
112 land.draw_line(island[island.len() - 1], island[0], value); |
|
113 } |
|
114 } |
|
115 } |
|
116 } |