44 |
44 |
45 pub fn total_len(&self) -> usize { |
45 pub fn total_len(&self) -> usize { |
46 self.islands.iter().map(|i| i.len()).sum::<usize>() + self.fill_points.len() |
46 self.islands.iter().map(|i| i.len()).sum::<usize>() + self.fill_points.len() |
47 } |
47 } |
48 |
48 |
|
49 pub fn iter(&self) -> impl Iterator<Item = &Point> { |
|
50 self.islands |
|
51 .iter() |
|
52 .flat_map(|i| i.iter()) |
|
53 .chain(self.fill_points.iter()) |
|
54 } |
|
55 |
49 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Point> { |
56 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Point> { |
50 self.islands |
57 self.islands |
51 .iter_mut() |
58 .iter_mut() |
52 .flat_map(|i| i.iter_mut()) |
59 .flat_map(|i| i.iter_mut()) |
53 .chain(self.fill_points.iter_mut()) |
60 .chain(self.fill_points.iter_mut()) |
54 } |
61 } |
55 |
62 |
56 fn divide_edge<I: Iterator<Item = u32>>( |
63 fn divide_edge<I: Iterator<Item = u32>>( |
57 &self, |
64 &self, |
58 segment: Line, |
65 segment: Line, |
|
66 distance_divisor: u32, |
59 random_numbers: &mut I, |
67 random_numbers: &mut I, |
60 ) -> Option<Point> { |
68 ) -> Option<Point> { |
|
69 #[inline] |
|
70 fn intersect(p: &Point, m: &Point, p1: &Point, p2: &Point) -> bool { |
|
71 let t1 = (m.x - p1.x) * p.y - p.x * (m.y - p1.y); |
|
72 let t2 = (m.x - p2.x) * p.y - p.x * (m.y - p2.y); |
|
73 |
|
74 (t1 > 0) != (t2 > 0) |
|
75 } |
|
76 |
|
77 #[inline] |
|
78 fn solve_intersection(p: &Point, m: &Point, s: &Point, e: &Point) -> Option<(i32, u32)> { |
|
79 let f = *e - *s; |
|
80 let aqpb = (p.x * f.y - f.x * p.y) as i64; |
|
81 |
|
82 if aqpb != 0 { |
|
83 let iy = ((((s.x - m.x) as i64 * p.y as i64 + m.y as i64 * p.x as i64) |
|
84 * f.y as i64 |
|
85 - s.y as i64 * f.x as i64 * p.y as i64) |
|
86 / aqpb) as i32; |
|
87 let ix = if p.y.abs() > f.y.abs() { |
|
88 (iy - m.y) * p.x / p.y + m.x |
|
89 } else { |
|
90 (iy - s.y) * f.x / f.y + s.x |
|
91 }; |
|
92 |
|
93 let intersection_point = Point::new(ix, iy); |
|
94 let diff_point = *m - intersection_point; |
|
95 let d = diff_point.integral_norm(); |
|
96 let t = p.y * diff_point.y + p.x * diff_point.x; |
|
97 |
|
98 Some((t, d)) |
|
99 } else { |
|
100 None |
|
101 } |
|
102 } |
|
103 |
61 let min_distance = 40; |
104 let min_distance = 40; |
62 // new point should fall inside this box |
105 // new point should fall inside this box |
63 let map_box = self.play_box.with_margin(min_distance); |
106 let map_box = self.play_box.with_margin(min_distance); |
64 |
107 |
65 let p = Point::new( |
108 let p = Point::new( |
123 dist_left = min(dist_left, dr); |
166 dist_left = min(dist_left, dr); |
124 } |
167 } |
125 } |
168 } |
126 |
169 |
127 // now go through all other segments |
170 // now go through all other segments |
128 |
171 for s in self.segments_iter() { |
129 None |
172 if s != segment { |
130 } |
173 if intersect(&p, &mid_point, &s.start, &s.end) { |
131 |
174 if let Some((t, d)) = solve_intersection(&p, &mid_point, &s.start, &s.end) { |
132 fn divide_edges<I: Iterator<Item = u32>>(&mut self, random_numbers: &mut I) { |
175 if t > 0 { |
|
176 dist_left = min(d, dist_left); |
|
177 } else { |
|
178 dist_right = min(d, dist_right); |
|
179 } |
|
180 } |
|
181 } |
|
182 } |
|
183 } |
|
184 |
|
185 // go through all points, including fill points |
|
186 for pi in self.iter() { |
|
187 if *pi != segment.start && *pi != segment.end { |
|
188 if intersect(&p, &pi, &segment.start, &segment.end) { |
|
189 // ray from segment.start |
|
190 if let Some((t, d)) = solve_intersection(&p, &mid_point, &segment.start, &pi) { |
|
191 if t > 0 { |
|
192 dist_left = min(d, dist_left); |
|
193 } else { |
|
194 dist_right = min(d, dist_right); |
|
195 } |
|
196 } |
|
197 |
|
198 // ray from segment.end |
|
199 if let Some((t, d)) = solve_intersection(&p, &mid_point, &segment.end, &pi) { |
|
200 if t > 0 { |
|
201 dist_left = min(d, dist_left); |
|
202 } else { |
|
203 dist_right = min(d, dist_right); |
|
204 } |
|
205 } |
|
206 } |
|
207 } |
|
208 } |
|
209 |
|
210 let max_dist = p.integral_norm() * 100 / distance_divisor; |
|
211 dist_left = min(dist_left, max_dist); |
|
212 dist_right = min(dist_right, max_dist); |
|
213 |
|
214 if dist_right + dist_left < min_distance as u32 * 2 + 10 { |
|
215 // limits are too narrow, just divide |
|
216 Some(mid_point) |
|
217 } else { |
|
218 // select distance within [-dist_left; dist_right], keeping min_distance in mind |
|
219 let d = -(dist_left as i32) |
|
220 + min_distance |
|
221 + random_numbers.next().unwrap() as i32 |
|
222 % (dist_right as i32 + dist_left as i32 - min_distance * 2); |
|
223 |
|
224 Some(Point::new( |
|
225 mid_point.x + p.x * d / distance_divisor as i32, |
|
226 mid_point.y + p.y * d / distance_divisor as i32, |
|
227 )) |
|
228 } |
|
229 } |
|
230 |
|
231 fn divide_edges<I: Iterator<Item = u32>>( |
|
232 &mut self, |
|
233 distance_divisor: u32, |
|
234 random_numbers: &mut I, |
|
235 ) { |
133 for is in 0..self.islands.len() { |
236 for is in 0..self.islands.len() { |
134 let mut i = 0; |
237 let mut i = 0; |
135 let mut segment; |
238 let mut segment; |
136 |
239 |
137 loop { |
240 loop { |
149 } |
252 } |
150 |
253 |
151 segment = Line::new(island[i], end_point); |
254 segment = Line::new(island[i], end_point); |
152 } |
255 } |
153 |
256 |
154 if let Some(new_point) = self.divide_edge(segment, random_numbers) { |
257 if let Some(new_point) = self.divide_edge(segment, distance_divisor, random_numbers) |
|
258 { |
155 self.islands[is].insert(i + 1, new_point); |
259 self.islands[is].insert(i + 1, new_point); |
156 i += 2; |
260 i += 2; |
157 } else { |
261 } else { |
158 i += 1; |
262 i += 1; |
159 } |
263 } |
160 } |
264 } |
161 } |
265 } |
162 } |
266 } |
163 |
267 |
164 pub fn bezierize(&mut self) { |
268 pub fn bezierize(&mut self) {} |
165 unimplemented!() |
269 |
166 } |
270 pub fn distort<I: Iterator<Item = u32>>( |
167 |
271 &mut self, |
168 pub fn distort<I: Iterator<Item = u32>>(&mut self, random_numbers: &mut I) { |
272 distance_divisor: u32, |
|
273 random_numbers: &mut I, |
|
274 ) { |
169 loop { |
275 loop { |
170 let old_len = self.total_len(); |
276 let old_len = self.total_len(); |
171 self.divide_edges(random_numbers); |
277 self.divide_edges(distance_divisor, random_numbers); |
172 |
278 |
173 if self.total_len() == old_len { |
279 if self.total_len() == old_len { |
174 break; |
280 break; |
175 } |
281 } |
176 } |
282 } |
191 index: 0, |
297 index: 0, |
192 } |
298 } |
193 } |
299 } |
194 |
300 |
195 pub fn mirror(&mut self) { |
301 pub fn mirror(&mut self) { |
196 let width = self.size.width as i32; |
302 let r = self.size.width as i32 - 1; |
197 self.iter_mut() |
303 |
198 .for_each(|p| p.x = width - 1 - p.x); |
304 self.iter_mut().for_each(|p| p.x = r - p.x); |
199 } |
305 } |
200 |
306 |
201 pub fn flip(&mut self) { |
307 pub fn flip(&mut self) { |
202 let height = self.size.height as i32; |
308 let t = self.size.height as i32 - 1; |
203 self.iter_mut() |
309 |
204 .for_each(|p| p.y = height - 1 - p.y); |
310 self.iter_mut().for_each(|p| p.y = t - p.y); |
205 } |
311 } |
206 } |
312 } |
207 |
313 |
208 struct OutlineSegmentsIterator<'a> { |
314 struct OutlineSegmentsIterator<'a> { |
209 outline: &'a OutlinePoints, |
315 outline: &'a OutlinePoints, |