2 extern crate vec2d; |
2 extern crate vec2d; |
3 |
3 |
4 use std::cmp; |
4 use std::cmp; |
5 use std::ops; |
5 use std::ops; |
6 |
6 |
7 use integral_geometry::{ArcPoints, EquidistantPoints, LinePoints, Point}; |
7 use integral_geometry::{ |
|
8 ArcPoints, EquidistantPoints, LinePoints, |
|
9 Point, Size, SizeMask |
|
10 }; |
8 |
11 |
9 pub struct Land2D<T> { |
12 pub struct Land2D<T> { |
10 pixels: vec2d::Vec2D<T>, |
13 pixels: vec2d::Vec2D<T>, |
11 width_mask: usize, |
14 mask: SizeMask |
12 height_mask: usize, |
|
13 } |
15 } |
14 |
16 |
15 impl<T: Copy + PartialEq> Land2D<T> { |
17 impl<T: Copy + PartialEq> Land2D<T> { |
16 pub fn new(width: usize, height: usize, fill_value: T) -> Self { |
18 pub fn new(size: Size, fill_value: T) -> Self { |
17 assert!(width.is_power_of_two()); |
|
18 assert!(height.is_power_of_two()); |
|
19 |
|
20 Self { |
19 Self { |
21 pixels: vec2d::Vec2D::new(width, height, fill_value), |
20 pixels: vec2d::Vec2D::new(size, fill_value), |
22 width_mask: !(width - 1), |
21 mask: size.to_mask() |
23 height_mask: !(height - 1), |
|
24 } |
22 } |
25 } |
23 } |
26 |
24 |
27 #[inline] |
25 #[inline] |
28 pub fn width(&self) -> usize { |
26 pub fn width(&self) -> usize { |
34 self.pixels.height() |
32 self.pixels.height() |
35 } |
33 } |
36 |
34 |
37 #[inline] |
35 #[inline] |
38 pub fn is_valid_x(&self, x: i32) -> bool { |
36 pub fn is_valid_x(&self, x: i32) -> bool { |
39 (x as usize & self.width_mask) == 0 |
37 self.mask.contains_x(x as usize) |
40 } |
38 } |
41 |
39 |
42 #[inline] |
40 #[inline] |
43 pub fn is_valid_y(&self, y: i32) -> bool { |
41 pub fn is_valid_y(&self, y: i32) -> bool { |
44 (y as usize & self.height_mask) == 0 |
42 self.mask.contains_y(y as usize) |
45 } |
43 } |
46 |
44 |
47 #[inline] |
45 #[inline] |
48 pub fn is_valid_coordinate(&self, x: i32, y: i32) -> bool { |
46 pub fn is_valid_coordinate(&self, x: i32, y: i32) -> bool { |
49 self.is_valid_x(x) && self.is_valid_y(y) |
47 self.is_valid_x(x) && self.is_valid_y(y) |
267 mod tests { |
265 mod tests { |
268 use super::*; |
266 use super::*; |
269 |
267 |
270 #[test] |
268 #[test] |
271 fn basics() { |
269 fn basics() { |
272 let l: Land2D<u8> = Land2D::new(32, 64, 0); |
270 let l: Land2D<u8> = Land2D::new(Size::new(32, 64), 0); |
273 |
271 |
274 assert!(l.is_valid_coordinate(0, 0)); |
272 assert!(l.is_valid_coordinate(0, 0)); |
275 assert!(!l.is_valid_coordinate(-1, -1)); |
273 assert!(!l.is_valid_coordinate(-1, -1)); |
276 |
274 |
277 assert!(l.is_valid_coordinate(31, 63)); |
275 assert!(l.is_valid_coordinate(31, 63)); |
279 assert!(!l.is_valid_coordinate(31, 64)); |
277 assert!(!l.is_valid_coordinate(31, 64)); |
280 } |
278 } |
281 |
279 |
282 #[test] |
280 #[test] |
283 fn fill() { |
281 fn fill() { |
284 let mut l: Land2D<u8> = Land2D::new(128, 128, 0); |
282 let mut l: Land2D<u8> = Land2D::new(Size::square(128), 0); |
285 |
283 |
286 l.draw_line(Point::new(0, 0), Point::new(32, 96), 1); |
284 l.draw_line(Point::new(0, 0), Point::new(32, 96), 1); |
287 l.draw_line(Point::new(32, 96), Point::new(64, 32), 1); |
285 l.draw_line(Point::new(32, 96), Point::new(64, 32), 1); |
288 l.draw_line(Point::new(64, 32), Point::new(96, 80), 1); |
286 l.draw_line(Point::new(64, 32), Point::new(96, 80), 1); |
289 l.draw_line(Point::new(96, 80), Point::new(128, 0), 1); |
287 l.draw_line(Point::new(96, 80), Point::new(128, 0), 1); |