///|
/// A multi-octave sampler with configurable normalization and remapping.
pub(all) struct FractalSampler {
base : ValueNoise
octaves : Int
lacunarity : Double
gain : Double
} derive(Eq, Debug, ToJson)
///|
pub fn FractalSampler::new(
seed : UInt,
frequency : Double,
octaves : Int,
) -> FractalSampler {
{
base: ValueNoise::new(frequency, seed),
octaves,
lacunarity: 2.0,
gain: 0.5,
}
}
///|
pub fn FractalSampler::with_parameters(
self : FractalSampler,
lacunarity : Double,
gain : Double,
) -> FractalSampler {
{ ..self, lacunarity, gain }
}
///|
pub impl NoiseSampler for FractalSampler with fn sample_2d(self, x, y) {
fractal_noise(
self.base,
x,
y,
self.octaves,
lacunarity=self.lacunarity,
gain=self.gain,
)
}
///|
pub fn[N : NoiseSampler] turbulence(
sampler : N,
x : Double,
y : Double,
octaves : Int,
) -> Double {
fractal_noise(sampler, x, y, octaves).abs()
}
///|
pub fn[N : NoiseSampler] domain_warped_sample(
sampler : N,
x : Double,
y : Double,
strength : Double,
scale : Double,
octaves : Int,
) -> Double {
let (wx, wy) = warp_point(sampler, x, y, strength, scale)
fractal_noise(sampler, wx, wy, octaves)
}
///|
pub fn[N : NoiseSampler] vector_field(
sampler : N,
width : Int,
height : Int,
scale : Double,
) -> Array[Vec2] {
let result = []
if width > 0 && height > 0 {
for y in 0.. Double {
if input_max == input_min {
output_min
} else {
let t = (value - input_min) / (input_max - input_min)
output_min + (output_max - output_min) * t
}
}
///|
pub fn threshold_noise(
value : Double,
threshold : Double,
softness : Double,
) -> Double {
if softness <= 0.0 {
if value >= threshold {
1.0
} else {
0.0
}
} else {
smoothstep((value - threshold + softness) / (2.0 * softness))
}
}
///|
pub fn noise_ramp(
sampler : ValueNoise,
count : Int,
start : Double,
step : Double,
) -> Array[Double] {
let result = []
for i in 0..