Skip to content

Commit cd5b763

Browse files
committed
simplify borders management
A region's boundary is simply composed of the set of the cells that are farthest away from the pivot, but that are always inside of the region.
1 parent ee83651 commit cd5b763

File tree

2 files changed

+37
-46
lines changed

2 files changed

+37
-46
lines changed

src/main.rs

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,14 @@ fn main() {
1515
let cm = ColorMap::color(&m).unwrap();
1616
let regions = &m.regions;
1717

18-
let c1 = " ".on_red().to_string();
19-
let c2 = " ".on_blue().to_string();
20-
let c3 = " ".on_green().to_string();
21-
let c4 = " ".on_yellow().to_string();
18+
let c1 = " ".on_red().dimmed().to_string();
19+
let c2 = " ".on_blue().dimmed().to_string();
20+
let c3 = " ".on_green().dimmed().to_string();
21+
let c4 = " ".on_yellow().dimmed().to_string();
2222
let p1 = "X".on_red().to_string();
2323
let p2 = "X".on_blue().to_string();
2424
let p3 = "X".on_green().to_string();
2525
let p4 = "X".on_yellow().to_string();
26-
let pb = "X".on_black().to_string();
27-
let b = " ".on_black().to_string();
2826

2927
let mut dbg_display = vec![vec![" "; usize::from(dim.0)]; usize::from(dim.1)];
3028
for (y, row) in m.raster.iter().enumerate() {
@@ -38,20 +36,26 @@ fn main() {
3836
}
3937
}
4038

41-
for r in regions.iter() {
42-
for (x, y) in &r.boundary {
43-
dbg_display[y.floor() as usize][x.floor() as usize] = &b;
44-
}
45-
}
39+
// print boundaries
40+
// let b1 = "*".on_red().to_string();
41+
// let b2 = "*".on_blue().to_string();
42+
// let b3 = "*".on_green().to_string();
43+
// let b4 = "*".on_yellow().to_string();
44+
// for (rid, r) in regions.iter().enumerate() {
45+
// for (x, y) in &r.boundary {
46+
// dbg_display[usize::from(*y)][usize::from(*x)] = match cm.color_of_region(rid) {
47+
// Color::C1 => &b1,
48+
// Color::C2 => &b2,
49+
// Color::C3 => &b3,
50+
// Color::C4 => &b4,
51+
// };
52+
// }
53+
// }
54+
4655
for (rid, r) in regions.iter().enumerate() {
4756
let x = usize::from(r.pivot.0);
4857
let y = usize::from(r.pivot.1);
4958

50-
if dbg_display[y][x] == b {
51-
dbg_display[y][x] = &pb;
52-
continue;
53-
}
54-
5559
dbg_display[y][x] = match cm.color_of_region(rid) {
5660
Color::C1 => &p1,
5761
Color::C2 => &p2,

src/map.rs

Lines changed: 17 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::collections::HashSet;
22

33
use rand::prelude::*;
44

5-
pub type Point = (f32, f32);
5+
pub type Point = (u16, u16);
66
pub type RegionId = usize;
77

88
#[derive(Debug)]
@@ -13,22 +13,27 @@ pub struct Map {
1313

1414
#[derive(Debug)]
1515
pub struct Region {
16-
pub pivot: (u16, u16),
16+
/// seed point of the region
17+
pub pivot: Point,
18+
19+
/// the farthest points of the region that are still part of the region
1720
pub boundary: Vec<Point>,
21+
22+
/// all the regions that share a border this region
1823
pub neighbors: HashSet<RegionId>,
1924
}
2025

2126
impl Map {
22-
pub fn voronoi_like(rng: &mut impl Rng, (w, h): (u8, u8), npivots: usize) -> Self {
23-
assert!(w > 2);
24-
assert!(h > 2);
27+
pub fn voronoi_like(rng: &mut impl Rng, (w, h): (u16, u16), npivots: usize) -> Self {
28+
assert!(w > 0);
29+
assert!(h > 0);
2530

2631
// TODO: find a better way to generate distinct pivot points
2732
let mut regions = (0..npivots)
2833
.map(|_| Region {
2934
pivot: {
30-
let x = rng.gen_range(1, u16::from(w) - 1);
31-
let y = rng.gen_range(1, u16::from(h) - 1);
35+
let x = rng.gen_range(0, w);
36+
let y = rng.gen_range(0, h);
3237
(x, y)
3338
},
3439
boundary: vec![],
@@ -48,9 +53,6 @@ impl Map {
4853
canvas[y][x] = region_id;
4954
}
5055

51-
// TODO: it seems boundaries are a bit too thick in some cases, try to stick to boundaries
52-
// of 1pix so that it's easier to generate non piexelated boundaries in case of svg output
53-
// or similar
5456
loop {
5557
let mut changed = false;
5658

@@ -62,16 +64,7 @@ impl Map {
6264
let ox = i32::from(p.0);
6365
let oy = i32::from(p.1);
6466

65-
[
66-
// (ox - 1, oy - 1),
67-
// (ox - 1, oy + 1),
68-
// (ox + 1, oy - 1),
69-
// (ox + 1, oy + 1),
70-
(ox - 1, oy),
71-
(ox, oy - 1),
72-
(ox, oy + 1),
73-
(ox + 1, oy),
74-
]
67+
[(ox - 1, oy), (ox, oy - 1), (ox, oy + 1), (ox + 1, oy)]
7568
};
7669

7770
for &(x, y) in &neighbors {
@@ -81,10 +74,9 @@ impl Map {
8174
let x = x as u16;
8275
let y = y as u16;
8376

84-
let on_boundary =
85-
x == 0 || x == u16::from(w) - 1 || y == 0 || y == u16::from(h) - 1;
77+
let on_boundary = x == 0 || x == w - 1 || y == 0 || y == h - 1;
8678

87-
let mut closest_rid = canvas[y as usize][x as usize];
79+
let mut closest_rid = canvas[usize::from(y)][usize::from(x)];
8880
if closest_rid >= regions.len() {
8981
canvas[usize::from(y)][usize::from(x)] = region_id;
9082
closest_rid = region_id;
@@ -94,14 +86,9 @@ impl Map {
9486
if closest_rid != region_id {
9587
regions[region_id].neighbors.insert(closest_rid);
9688
regions[closest_rid].neighbors.insert(region_id);
97-
regions[region_id].boundary.push((
98-
(f32::from(x) + f32::from(p.0)) / 2.0,
99-
(f32::from(y) + f32::from(p.1)) / 2.0,
100-
));
89+
regions[region_id].boundary.push(*p);
10190
} else if on_boundary {
102-
regions[region_id]
103-
.boundary
104-
.push((f32::from(x), f32::from(y)));
91+
regions[region_id].boundary.push((x, y));
10592
}
10693
}
10794
}

0 commit comments

Comments
 (0)