worldgen 0.5.3

Noisemap and world generation library
Documentation
//////////////////////////////////////////////////////////////////////////////
//  File: rust-worldgen/noise/perlin/mod.rs
//////////////////////////////////////////////////////////////////////////////
//  Copyright 2015 Samuel Sleight
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//////////////////////////////////////////////////////////////////////////////

//! A provider of perlin noise.
//!
//! Perlin noise is generated by combining a number of different values
//! of coherent noise (known as octaves).
//!
//! The perlin noise source has a number of different properties that can
//! be customised: the number of octaves, and the frequency, persistence,
//! and lacunarity of the noise.

use std::default::Default;

use super::NoiseProvider;
use super::coherent::CoherentNoise;

pub use self::property::{Octaves, Frequency, Persistence, Lacunarity};
use self::property::Property;

mod property;

/// The perlin noise source
///
/// # Example
///
/// ```
/// # use worldgen::noise::perlin::{PerlinNoise, Octaves};
/// # use worldgen::noise::NoiseProvider;
/// let noise = PerlinNoise::new()
///     .set(Octaves::of(5));
///
/// let value = noise.generate(1.5, 2.5, 15);
/// ```
#[derive(Default, Debug, Copy, Clone)]
pub struct PerlinNoise {
    octaves: Octaves,
    freq: Frequency,
    pers: Persistence,
    lacu: Lacunarity
}

impl PerlinNoise {
    /// Construct the default perlin source.
    ///
    /// The default values are:
    ///
    /// ```text
    /// octaves = 8
    /// frequency = 1.0
    /// persistence = 0.5
    /// lacunarity = 2.0
    /// ```
    pub fn new() -> PerlinNoise {
        Default::default()
    }

    /// Set a property on the noise source.
    pub fn set<T: Property>(self, property: T) -> PerlinNoise {
        property.set_to(self)
    }

    fn set_octaves(self, octaves: Octaves) -> PerlinNoise {
        PerlinNoise {
            octaves,
            ..self
        }
    }

    fn set_frequency(self, freq: Frequency) -> PerlinNoise {
        PerlinNoise {
            freq,
            ..self
        }
    }

    fn set_persistence(self, pers: Persistence) -> PerlinNoise {
        PerlinNoise {
            pers,
            ..self
        }
    }

    fn set_lacunarity(self, lacu: Lacunarity) -> PerlinNoise {
        PerlinNoise {
            lacu,
            ..self
        }
    }
}

impl NoiseProvider for PerlinNoise {
    fn generate(&self, x: f64, y: f64, seed: u64) -> f64 {
        let mut x = x * self.freq.value;
        let mut y = y * self.freq.value;
        let mut pers = 1.0f64;

        (0 .. self.octaves.value).fold(0.0, |value, octave| {
            let seed = seed + octave as u64;
            let value = value + CoherentNoise.generate(x, y, seed) * pers;

            x *= self.lacu.value;
            y *= self.lacu.value;
            pers *= self.pers.value;

            value
        })
    }
}