1 use land2d::Land2D; |
1 use vec2d::Vec2D; |
2 use std::rc::Rc; |
2 use std::rc::Rc; |
|
3 use integral_geometry::Size; |
3 |
4 |
4 pub struct TileImage { |
5 pub struct TileImage<T> { |
5 image: Rc<Land2D<u8>>, |
6 image: Rc<Vec2D<T>>, |
6 flip: bool, |
7 flip: bool, |
7 mirror: bool, |
8 mirror: bool, |
8 } |
9 } |
9 |
10 |
10 impl TileImage { |
11 impl<T: Copy> TileImage<T> { |
11 pub fn new(flip: bool, mirror: bool) -> Self { |
12 pub fn new(image: Vec2D<T>) -> Self { |
12 Self { |
13 Self { |
13 image: todo!(), |
14 image: Rc::new(image), |
14 flip, |
15 flip: false, |
15 mirror, |
16 mirror: false, |
16 } |
17 } |
17 } |
18 } |
18 |
19 |
19 pub fn mirrored(&self) -> Self { |
20 pub fn mirrored(&self) -> Self { |
20 Self { |
21 Self { |
21 image: self.image.clone(), |
22 image: self.image.clone(), |
22 flip: self.flip, |
23 flip: self.flip, |
23 mirror: !self.mirror |
24 mirror: !self.mirror, |
24 } |
25 } |
25 } |
26 } |
26 |
27 |
27 pub fn flipped(&self) -> Self { |
28 pub fn flipped(&self) -> Self { |
28 Self { |
29 Self { |
29 image: self.image.clone(), |
30 image: self.image.clone(), |
30 flip: !self.flip, |
31 flip: !self.flip, |
31 mirror: self.mirror |
32 mirror: self.mirror, |
32 } |
33 } |
33 } |
34 } |
|
35 |
|
36 pub fn split(&self, rows: usize, columns: usize) -> Vec<TileImage<T>> { |
|
37 let mut result = Vec::new(); |
|
38 let self_image = self.image.as_ref(); |
|
39 let (result_width, result_height) = (self_image.width() / columns, self.image.height() / rows); |
|
40 |
|
41 for row in 0..rows { |
|
42 for column in 0..columns { |
|
43 let mut tile_pixels = Vec::new(); |
|
44 |
|
45 for out_row in 0..result_height { |
|
46 tile_pixels.push(self_image[row * result_height + out_row][column*result_width..(column+1)*result_width].iter()); |
|
47 } |
|
48 |
|
49 let tile_image = Vec2D::from_iter(tile_pixels.into_iter().flatten().map(|p| *p), &Size::new(result_width, result_height)); |
|
50 |
|
51 result.push(TileImage::new(tile_image.expect("correct calculation of tile dimensions"))); |
|
52 } |
|
53 } |
|
54 |
|
55 result |
|
56 } |
34 } |
57 } |
|
58 |
|
59 #[cfg(test)] |
|
60 mod tests { |
|
61 use super::TileImage; |
|
62 use integral_geometry::Size; |
|
63 use vec2d::Vec2D; |
|
64 |
|
65 #[test] |
|
66 fn test_split() { |
|
67 let size = Size::new(6, 4); |
|
68 let sample_data = Vec2D::from_iter((0..24).into_iter(), &size); |
|
69 |
|
70 assert!(sample_data.is_some()); |
|
71 |
|
72 let sample_data = sample_data.unwrap(); |
|
73 let big_tile = TileImage::new(sample_data); |
|
74 let subtiles = big_tile.split(2, 2); |
|
75 |
|
76 assert_eq!(subtiles.len(), 4); |
|
77 } |
|
78 } |