Skip to main content

world_gen/
heightmap.rs

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    /// Creates a new `HeightMap` instance.
16    /// # Examples
17    /// ```
18    /// use world_gen::heightmap::HeightMap;
19    ///
20    /// let height = 300;
21    /// let width = 400;
22    /// let seed = 12345;
23    /// let map = HeightMap::new(height, width, seed);
24    /// for x in 0..height {
25    ///     for y in 0..width {
26    ///         // Iterates over each point in the heightmap
27    ///     }
28    /// }
29    /// ```
30    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}