1use super::{chunk::Chunk, point::Point};
2use num_integer::Integer;
3use serde::{Deserialize, Serialize};
4
5#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, Hash)]
6pub struct Rect {
7 width: usize,
8 height: usize,
9}
10
11impl Rect {
12 pub fn new(width: usize, height: usize) -> Self {
13 Self { width, height }
14 }
15
16 pub fn width(&self) -> usize {
17 self.width
18 }
19
20 pub fn height(&self) -> usize {
21 self.height
22 }
23
24 pub fn area(&self) -> usize {
25 self.width * self.height
26 }
27
28 pub fn divide(&self, rect: &Rect) -> Vec<Chunk> {
29 let (x_count, x_remainder) = self.width.div_rem(&rect.width);
30 let (y_count, y_remainder) = self.height.div_rem(&rect.height);
31 let count = match (x_remainder, y_remainder) {
32 (0, 0) => x_count * y_count,
33 (0, _) => x_count * y_count + x_count,
34 (_, 0) => x_count * y_count + y_count,
35 (_, _) => x_count * y_count + x_count + y_count + 1,
36 };
37 let mut buffer = Vec::with_capacity(count);
38
39 for y in 0..y_count {
40 for x in 0..x_count {
41 buffer.push(Chunk::new(
42 Point::new(x * rect.width, y * rect.height),
43 Self::new(rect.width, rect.height),
44 ));
45 }
46 }
47 if x_remainder != 0 {
48 for y in 0..y_count {
49 buffer.push(Chunk::new(
50 Point::new(x_count * rect.width, y * rect.height),
51 Self::new(x_remainder, rect.height),
52 ));
53 }
54 }
55 if y_remainder != 0 {
56 for x in 0..x_count {
57 buffer.push(Chunk::new(
58 Point::new(x * rect.width, y_count * rect.height),
59 Self::new(rect.width, y_remainder),
60 ));
61 }
62 }
63 if x_remainder != 0 && y_remainder != 0 {
64 buffer.push(Chunk::new(
65 Point::new(x_count * rect.width, y_count * rect.height),
66 Self::new(x_remainder, y_remainder),
67 ));
68 }
69
70 buffer
71 }
72}