1 use std::{ |
1 use std::{cmp, ops::Index}; |
2 cmp, |
2 |
3 ops::Index |
3 use integral_geometry::{ArcPoints, EquidistantPoints, Line, Point, PotSize, Rect, Size, SizeMask}; |
4 }; |
|
5 |
|
6 use integral_geometry::{ArcPoints, EquidistantPoints, Line, Point, Rect, Size, SizeMask}; |
|
7 |
4 |
8 pub struct Land2D<T> { |
5 pub struct Land2D<T> { |
9 pixels: vec2d::Vec2D<T>, |
6 pixels: vec2d::Vec2D<T>, |
10 play_box: Rect, |
7 play_box: Rect, |
11 mask: SizeMask, |
8 mask: SizeMask, |
13 |
10 |
14 impl<T: Copy + PartialEq> Land2D<T> { |
11 impl<T: Copy + PartialEq> Land2D<T> { |
15 pub fn new(play_size: Size, fill_value: T) -> Self { |
12 pub fn new(play_size: Size, fill_value: T) -> Self { |
16 let real_size = play_size.next_power_of_two(); |
13 let real_size = play_size.next_power_of_two(); |
17 let top_left = Point::new( |
14 let top_left = Point::new( |
18 ((real_size.width - play_size.width) / 2) as i32, |
15 ((real_size.width() - play_size.width) / 2) as i32, |
19 (real_size.height - play_size.height) as i32, |
16 (real_size.height() - play_size.height) as i32, |
20 ); |
17 ); |
21 let play_box = Rect::from_size(top_left, play_size); |
18 let play_box = Rect::from_size(top_left, play_size); |
22 Self { |
19 Self { |
23 play_box, |
20 play_box, |
24 pixels: vec2d::Vec2D::new(real_size, fill_value), |
21 pixels: vec2d::Vec2D::new(real_size.size(), fill_value), |
25 mask: real_size.to_mask(), |
22 mask: real_size.to_mask(), |
26 } |
23 } |
27 } |
24 } |
28 |
25 |
29 pub fn raw_pixels(&self) -> &[T] { |
26 pub fn raw_pixels(&self) -> &[T] { |
30 &self.pixels.as_slice() |
27 &self.pixels.as_slice() |
31 } |
28 } |
32 |
29 |
33 pub fn raw_pixel_bytes(&self) -> &[u8] { |
30 pub fn raw_pixel_bytes(&self) -> &[u8] { |
34 unsafe { |
31 unsafe { self.pixels.as_bytes() } |
35 self.pixels.as_bytes() |
|
36 } |
|
37 } |
32 } |
38 |
33 |
39 #[inline] |
34 #[inline] |
40 pub fn width(&self) -> usize { |
35 pub fn width(&self) -> usize { |
41 self.pixels.width() |
36 self.pixels.width() |
115 i.map(|p| { |
110 i.map(|p| { |
116 self.map(p.y, p.x, |v| { |
111 self.map(p.y, p.x, |v| { |
117 *v = value; |
112 *v = value; |
118 1 |
113 1 |
119 }) |
114 }) |
120 }).count() |
115 }) |
|
116 .count() |
121 } |
117 } |
122 |
118 |
123 pub fn draw_line(&mut self, line: Line, value: T) -> usize { |
119 pub fn draw_line(&mut self, line: Line, value: T) -> usize { |
124 self.fill_from_iter(line.into_iter(), value) |
120 self.fill_from_iter(line.into_iter(), value) |
125 } |
121 } |
147 }; |
143 }; |
148 |
144 |
149 let start_x_l = (start_point.x - 1) as usize; |
145 let start_x_l = (start_point.x - 1) as usize; |
150 let start_x_r = start_point.x as usize; |
146 let start_x_r = start_point.x as usize; |
151 for dir in [-1, 1].iter().cloned() { |
147 for dir in [-1, 1].iter().cloned() { |
152 push(mask, &mut stack, start_x_l, start_x_r, start_point.y as usize, dir); |
148 push( |
|
149 mask, |
|
150 &mut stack, |
|
151 start_x_l, |
|
152 start_x_r, |
|
153 start_point.y as usize, |
|
154 dir, |
|
155 ); |
153 } |
156 } |
154 |
157 |
155 while let Some((mut xl, mut xr, y, dir)) = stack.pop() { |
158 while let Some((mut xl, mut xr, y, dir)) = stack.pop() { |
156 let row = &mut self.pixels[y][..]; |
159 let row = &mut self.pixels[y][..]; |
157 while xl > 0 && row[xl] != border_value && row[xl] != fill_value |
160 while xl > 0 && row[xl] != border_value && row[xl] != fill_value { |
158 { |
|
159 xl -= 1; |
161 xl -= 1; |
160 } |
162 } |
161 |
163 |
162 while xr < width - 1 && row[xr] != border_value && row[xr] != fill_value |
164 while xr < width - 1 && row[xr] != border_value && row[xr] != fill_value { |
163 { |
|
164 xr += 1; |
165 xr += 1; |
165 } |
166 } |
166 |
167 |
167 while xl < xr { |
168 while xl < xr { |
168 while xl <= xr && (row[xl] == border_value || row[xl] == fill_value) |
169 while xl <= xr && (row[xl] == border_value || row[xl] == fill_value) { |
169 { |
|
170 xl += 1; |
170 xl += 1; |
171 } |
171 } |
172 |
172 |
173 let x = xl; |
173 let x = xl; |
174 |
174 |
175 while xl <= xr && row[xl] != border_value && row[xl] != fill_value |
175 while xl <= xr && row[xl] != border_value && row[xl] != fill_value { |
176 { |
|
177 row[xl] = fill_value; |
176 row[xl] = fill_value; |
178 xl += 1; |
177 xl += 1; |
179 } |
178 } |
180 |
179 |
181 if x < xl { |
180 if x < xl { |