noise/noise_fns/modifiers/
exponent.rs

1use crate::{math::scale_shift, noise_fns::NoiseFn};
2use core::marker::PhantomData;
3
4#[cfg(feature = "libm")]
5use num_traits::Float;
6
7/// Noise function that maps the output value from the source function onto an
8/// exponential curve.
9///
10/// Because most noise functions will output values that range from -1.0 to 1.0,
11/// this noise function first normalizes the output value (the range becomes 0.0
12/// to 1.0), maps that value onto an exponential curve, then rescales that
13/// value back to the original range.
14#[derive(Clone, Debug)]
15pub struct Exponent<T, Source, const DIM: usize>
16where
17    Source: NoiseFn<T, DIM>,
18{
19    /// Outputs a value.
20    pub source: Source,
21
22    /// Exponent to apply to the output value from the source function. Default
23    /// is 1.0.
24    pub exponent: f64,
25
26    phantom: PhantomData<T>,
27}
28
29impl<T, Source, const DIM: usize> Exponent<T, Source, DIM>
30where
31    Source: NoiseFn<T, DIM>,
32{
33    pub fn new(source: Source) -> Self {
34        Self {
35            source,
36            exponent: 1.0,
37            phantom: PhantomData,
38        }
39    }
40
41    pub fn set_exponent(self, exponent: f64) -> Self {
42        Self { exponent, ..self }
43    }
44}
45
46impl<T, Source, const DIM: usize> NoiseFn<T, DIM> for Exponent<T, Source, DIM>
47where
48    Source: NoiseFn<T, DIM>,
49{
50    fn get(&self, point: [T; DIM]) -> f64 {
51        let mut value = self.source.get(point);
52        value = (value + 1.0) / 2.0;
53        value = value.abs();
54        value = value.powf(self.exponent);
55        scale_shift(value, 2.0)
56    }
57}