Simple Coordinate Subdivision in Rust
Just a quick little post about a simple topic. I want to subdivide my square game map into X by X squares for various reasons...some current reasons, and some future reasons.
I want to more efficiently narrow down parts of the map to change for my erosion simulation. It's also something close to what I'll need in the future because I plan on eventually dealing with my map in 256x256 tile chunks. That's a topic for the future though.
Here's the quick and dirty code:
pub struct Section {
pub from: (usize, usize),
pub to: (usize, usize),
}
impl Section {
pub fn with_width(width: usize) -> Self {
Self {
from: (0, 0),
to: (width - 1, width - 1),
}
}
pub fn subdivide(&self, divisor: usize) -> Vec<Section> {
let mut retval: Vec<Section> = vec![];
let width = (self.to.0 - self.from.0) + 1;
if divisor < 2 || width < 2 {
return retval;
}
let step = width / divisor;
let mut x1 = 0;
let mut y1 = 0;
let mut x2 = step - 1;
let mut y2 = step - 1;
while y2 < width {
retval.push(Section {
from: (self.from.0 + x1, self.from.1 + y1),
to: (self.from.0 + x2, self.from.1 + y2),
});
x1 += step;
x2 = x1 + step - 1;
if x1 > width - 1 {
x1 = 0;
x2 = step - 1;
y1 += step;
y2 = y1 + step - 1;
}
}
retval
}
}
One caveat: it's only perfect if width modulo divisor == 0. This is all I need though, so it's all I wrote. However, even if you use it on a width that doesn't evenly divide, all the coordinates will still be valid, but a bit of the area will be left out. (at least (width % divisor) * width?)
With the following test code:
let s = Section::with_width(99);
let s2 = s.subdivide(11);
let s3 = s2[0].subdivide(3);
When I render each square in s2 with alternating colors it looks like this (11x11 squares, 9x9 pixels each):
When I render s3 it looks like this (the first of the previous squares further subdivided into 3x3 squares, 3x3 pixels each):
(the grey on grey grid background is just my standard background for my test images, and these images are scaled up 4x)
That's pretty much it. For the Section struct, from = the upper left corner of the square, to = the lower right corner of the square. There's no concept of pixels, tiles, etc. in this code...it's just coordinates I can make squares with.
Cheers!