1use noise::{Perlin, Seedable, NoiseFn};
2
3
4pub type HeightMapDataCol = Vec<f64>;
5pub type HeightMapData = Vec<HeightMapDataCol>;
6
7pub struct HeightMap {
8 pub height: u32,
9 pub width: u32,
10 pub seed: u32,
11 pub data: HeightMapData
12}
13
14impl HeightMap {
15 pub fn new(height: u32, width: u32, seed: u32) -> HeightMap {
31 let map_data = HeightMap::gen(height, width, seed);
32 HeightMap {
33 height,
34 width,
35 seed,
36 data: map_data
37 }
38 }
39
40 fn gen(height: u32, width: u32, seed: u32) -> HeightMapData {
41 let noise = Perlin::new().set_seed(seed);
42 let mut map = HeightMapData::new();
43 for x in 0..width {
44 map.push(HeightMap::gen_column(x, height, width, noise));
45 }
46 map
47 }
48
49 fn gen_column(x: u32, height: u32, width: u32, noise: Perlin) -> HeightMapDataCol {
50 let mut col = HeightMapDataCol::new();
51 for y in 0..height {
52 let nx: f64 = x as f64 / width as f64 - 0.5;
53 let ny: f64 = y as f64 / height as f64 - 0.5;
54 let elevation = HeightMap::get_point(nx, ny, noise);
55 col.push(elevation);
56 }
57 col
58 }
59
60 fn get_point(x: f64, y: f64, noise: Perlin) -> f64 {
61 let mut val = noise.get([x, y]);
62 val += 0.5 * noise.get([2.0 * x, 2.0 * y]);
63 val += 0.25 * noise.get([4.0 * x, 2.0 * y]);
64 val += 1.0;
65 val = val / 2.0;
66 val
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[test]
75 fn new_heightmap() {
76 let height = 50;
77 let width = 40;
78 let seed = 12345;
79 let map = HeightMap::new(height, width, seed);
80 assert_eq!(map.height, height);
81 assert_eq!(map.width, width);
82 assert_eq!(map.seed, seed);
83 assert_eq!(map.data.len() as u32, map.width);
84 for x in 0..width {
85 assert_eq!(map.data[x as usize].len() as u32, map.height);
86 }
87 }
88}