59 } else { |
59 } else { |
60 U::default() |
60 U::default() |
61 } |
61 } |
62 } |
62 } |
63 |
63 |
64 fn apply_along_line<U: Default + ops::AddAssign, F: FnMut(i32, i32) -> U>( |
64 #[inline] |
65 x1: i32, |
65 pub fn map_point<U: Default, F: FnOnce(&mut T) -> U>(&mut self, point: Point, f: F) -> U { |
66 y1: i32, |
66 self.map(point.y, point.x, f) |
67 x2: i32, |
|
68 y2: i32, |
|
69 f: &mut F, |
|
70 ) -> U { |
|
71 let mut result = U::default(); |
|
72 let mut e_x: i32 = 0; |
|
73 let mut e_y: i32 = 0; |
|
74 let mut d_x: i32 = x2 - x1; |
|
75 let mut d_y: i32 = y2 - y1; |
|
76 |
|
77 let s_x: i32; |
|
78 let s_y: i32; |
|
79 |
|
80 if d_x > 0 { |
|
81 s_x = 1; |
|
82 } else if d_x < 0 { |
|
83 s_x = -1; |
|
84 d_x = -d_x; |
|
85 } else { |
|
86 s_x = d_x; |
|
87 } |
|
88 |
|
89 if d_y > 0 { |
|
90 s_y = 1; |
|
91 } else if d_y < 0 { |
|
92 s_y = -1; |
|
93 d_y = -d_y; |
|
94 } else { |
|
95 s_y = d_y; |
|
96 } |
|
97 |
|
98 let d = cmp::max(d_x, d_y); |
|
99 |
|
100 let mut x = x1; |
|
101 let mut y = y1; |
|
102 |
|
103 for _i in 0..=d { |
|
104 e_x += d_x; |
|
105 e_y += d_y; |
|
106 |
|
107 if e_x > d { |
|
108 e_x -= d; |
|
109 x += s_x; |
|
110 } |
|
111 if e_y > d { |
|
112 e_y -= d; |
|
113 y += s_y; |
|
114 } |
|
115 |
|
116 result += f(x, y); |
|
117 } |
|
118 |
|
119 result |
|
120 } |
|
121 |
|
122 fn apply_around_circle<U: Default + ops::AddAssign, F: FnMut(i32, i32) -> U>( |
|
123 radius: i32, |
|
124 f: &mut F, |
|
125 ) -> U { |
|
126 let mut dx: i32 = 0; |
|
127 let mut dy: i32 = radius; |
|
128 let mut d = 3 - 2 * radius; |
|
129 let mut result = U::default(); |
|
130 |
|
131 while dx < dy { |
|
132 result += f(dx, dy); |
|
133 |
|
134 if d < 0 { |
|
135 d += 4 * dx + 6; |
|
136 } else { |
|
137 d += 4 * (dx - dy) + 10; |
|
138 dy -= 1; |
|
139 } |
|
140 |
|
141 dx += 1; |
|
142 } |
|
143 |
|
144 if dx == dy { |
|
145 result += f(dx, dy); |
|
146 } |
|
147 |
|
148 result |
|
149 } |
67 } |
150 |
68 |
151 pub fn fill_from_iter<I>(&mut self, i: I, value: T) -> usize |
69 pub fn fill_from_iter<I>(&mut self, i: I, value: T) -> usize |
152 where |
70 where |
153 I: std::iter::Iterator<Item = Point>, |
71 I: std::iter::Iterator<Item = Point>, |
288 ArcPoints::new(radius) |
206 ArcPoints::new(radius) |
289 .map(&mut |p: Point| self.fill_circle_lines(x, y, p.x, p.y, &f)) |
207 .map(&mut |p: Point| self.fill_circle_lines(x, y, p.x, p.y, &f)) |
290 .sum() |
208 .sum() |
291 } |
209 } |
292 |
210 |
293 #[inline] |
211 pub fn draw_thick_line(&mut self, from: Point, to: Point, radius: i32, value: T) -> usize { |
294 fn change_dots_around<U: Default + ops::AddAssign, F: FnMut(i32, i32) -> U>( |
212 let mut result = 0; |
295 x: i32, |
213 |
296 y: i32, |
214 for point in LinePoints::new(from, to) { |
297 xx: i32, |
215 for vector in ArcPoints::new(radius) { |
298 yy: i32, |
216 for delta in EquidistantPoints::new(vector) { |
299 f: &mut F, |
217 self.map_point(point + delta, |p| { |
300 ) -> U { |
|
301 let mut result = U::default(); |
|
302 result += f(y + yy, x + xx); |
|
303 result += f(y - yy, x + xx); |
|
304 result += f(y + yy, x - xx); |
|
305 result += f(y - yy, x - xx); |
|
306 result += f(y + xx, x + yy); |
|
307 result += f(y - xx, x + yy); |
|
308 result += f(y + xx, x - yy); |
|
309 result += f(y - xx, x - yy); |
|
310 |
|
311 result |
|
312 } |
|
313 |
|
314 pub fn draw_thick_line( |
|
315 &mut self, |
|
316 from: Point, to: Point, |
|
317 radius: i32, |
|
318 value: T, |
|
319 ) -> usize { |
|
320 for deltas in ArcPoints::new(radius) { |
|
321 for points in LinePoints::new(from, to) { |
|
322 |
|
323 } |
|
324 } |
|
325 |
|
326 <Land2D<T>>::apply_around_circle(radius, &mut |dx, dy| { |
|
327 <Land2D<T>>::apply_along_line(x1, y1, x2, y2, &mut |x, y| { |
|
328 <Land2D<T>>::change_dots_around(x, y, dx, dy, &mut |x, y| { |
|
329 self.map(x, y, |p| { |
|
330 if *p != value { |
218 if *p != value { |
331 *p = value; |
219 *p = value; |
332 1 |
220 result += 1; |
333 } else { |
|
334 0 |
|
335 } |
221 } |
336 }) |
222 }) |
337 }) |
223 } |
338 }) |
224 } |
339 }) |
225 } |
|
226 |
|
227 result |
340 } |
228 } |
341 } |
229 } |
342 |
230 |
343 #[cfg(test)] |
231 #[cfg(test)] |
344 mod tests { |
232 mod tests { |