worldgen/noise/perlin/mod.rs
1//////////////////////////////////////////////////////////////////////////////
2// File: rust-worldgen/noise/perlin/mod.rs
3//////////////////////////////////////////////////////////////////////////////
4// Copyright 2015 Samuel Sleight
5//
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17//////////////////////////////////////////////////////////////////////////////
18
19//! A provider of perlin noise.
20//!
21//! Perlin noise is generated by combining a number of different values
22//! of coherent noise (known as octaves).
23//!
24//! The perlin noise source has a number of different properties that can
25//! be customised: the number of octaves, and the frequency, persistence,
26//! and lacunarity of the noise.
27
28use std::default::Default;
29
30use super::NoiseProvider;
31use super::coherent::CoherentNoise;
32
33pub use self::property::{Octaves, Frequency, Persistence, Lacunarity};
34use self::property::Property;
35
36mod property;
37
38/// The perlin noise source
39///
40/// # Example
41///
42/// ```
43/// # use worldgen::noise::perlin::{PerlinNoise, Octaves};
44/// # use worldgen::noise::NoiseProvider;
45/// let noise = PerlinNoise::new()
46/// .set(Octaves::of(5));
47///
48/// let value = noise.generate(1.5, 2.5, 15);
49/// ```
50#[derive(Default, Debug, Copy, Clone)]
51pub struct PerlinNoise {
52 octaves: Octaves,
53 freq: Frequency,
54 pers: Persistence,
55 lacu: Lacunarity
56}
57
58impl PerlinNoise {
59 /// Construct the default perlin source.
60 ///
61 /// The default values are:
62 ///
63 /// ```text
64 /// octaves = 8
65 /// frequency = 1.0
66 /// persistence = 0.5
67 /// lacunarity = 2.0
68 /// ```
69 pub fn new() -> PerlinNoise {
70 Default::default()
71 }
72
73 /// Set a property on the noise source.
74 pub fn set<T: Property>(self, property: T) -> PerlinNoise {
75 property.set_to(self)
76 }
77
78 fn set_octaves(self, octaves: Octaves) -> PerlinNoise {
79 PerlinNoise {
80 octaves,
81 ..self
82 }
83 }
84
85 fn set_frequency(self, freq: Frequency) -> PerlinNoise {
86 PerlinNoise {
87 freq,
88 ..self
89 }
90 }
91
92 fn set_persistence(self, pers: Persistence) -> PerlinNoise {
93 PerlinNoise {
94 pers,
95 ..self
96 }
97 }
98
99 fn set_lacunarity(self, lacu: Lacunarity) -> PerlinNoise {
100 PerlinNoise {
101 lacu,
102 ..self
103 }
104 }
105}
106
107impl NoiseProvider for PerlinNoise {
108 fn generate(&self, x: f64, y: f64, seed: u64) -> f64 {
109 let mut x = x * self.freq.value;
110 let mut y = y * self.freq.value;
111 let mut pers = 1.0f64;
112
113 (0 .. self.octaves.value).fold(0.0, |value, octave| {
114 let seed = seed + octave as u64;
115 let value = value + CoherentNoise.generate(x, y, seed) * pers;
116
117 x *= self.lacu.value;
118 y *= self.lacu.value;
119 pers *= self.pers.value;
120
121 value
122 })
123 }
124}