@@ -2,7 +2,7 @@ use std::collections::HashSet;
22
33use rand:: prelude:: * ;
44
5- pub type Point = ( f32 , f32 ) ;
5+ pub type Point = ( u16 , u16 ) ;
66pub type RegionId = usize ;
77
88#[ derive( Debug ) ]
@@ -13,22 +13,27 @@ pub struct Map {
1313
1414#[ derive( Debug ) ]
1515pub 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
2126impl 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