[orx-noise] Add tools for functional composition

This commit is contained in:
Edwin Jakobs
2021-07-25 22:36:07 +02:00
parent c388cbe7e2
commit 454affbdfd
15 changed files with 532 additions and 74 deletions

View File

@@ -26,6 +26,27 @@ val v4ur = Vector4.uniformRing(0.5, 1.0)
val ringSamples = List(500) { Vector2.uniformRing() } val ringSamples = List(500) { Vector2.uniformRing() }
``` ```
## Noise function composition
Since ORX 0.4 the orx-noise module comes with functional composition tooling that allow one to create complex noise
functions.
```kotlin
// create an FBM version of 1D linear perlin noise
val myNoise0 = perlinLinear1D.fbm(octaves=3)
val noiseValue0 = myNoise0(431, seconds)
// create polar version of 2D simplex noise
val myNoise1 = simplex2D.withPolarInput()
val noiseValue1 = myNoise1(5509, Polar(seconds*60.0, 0.5))
// create value linear noise with squared outputs which is then billowed
val myNoise2 = valueLinear1D.mapOutput { it * it }.billow()
val noiseValue2 = myNoise2(993, seconds * 0.1)
```
## Multi-dimensional noise ## Multi-dimensional noise
These are a mostly straight port from FastNoise-Java but have a slightly different interface. These are a mostly straight port from FastNoise-Java but have a slightly different interface.

View File

@@ -8,3 +8,7 @@ fun cubicHermite(seed: Int, x: Double) = cubic(seed, x, ::hermite)
fun cubic(seed: Int, x: Double, interpolator: (Double) -> Double = ::linear): Double { fun cubic(seed: Int, x: Double, interpolator: (Double) -> Double = ::linear): Double {
return cubic(seed, x, 0.0, interpolator) return cubic(seed, x, 0.0, interpolator)
} }
val cubicLinear1D: (Int, Double) -> Double = ::cubicLinear
val cubicQuintic1D: (Int, Double) -> Double = ::cubicQuintic
val cubicHermite1D: (Int, Double) -> Double = ::cubicHermite

View File

@@ -39,3 +39,7 @@ fun cubic(seed: Int, x: Double, y: Double, interpolator: (Double) -> Double = ::
xs), xs),
ys) * CUBIC_2D_BOUNDING ys) * CUBIC_2D_BOUNDING
} }
val cubicLinear2D: (Int, Double, Double) -> Double = ::cubicLinear
val cubicQuintic2D: (Int, Double, Double) -> Double = ::cubicQuintic
val cubicHermite2D: (Int, Double, Double) -> Double = ::cubicHermite

View File

@@ -60,3 +60,7 @@ fun cubic(seed: Int, x: Double, y: Double, z: Double, interpolator: (Double) ->
ys), ys),
zs) * CUBIC_3D_BOUNDING zs) * CUBIC_3D_BOUNDING
} }
val cubicLinear3D: (Int, Double, Double, Double) -> Double = ::cubicLinear
val cubicQuintic3D: (Int, Double, Double, Double) -> Double = ::cubicQuintic
val cubicHermite3D: (Int, Double, Double, Double) -> Double = ::cubicHermite

View File

@@ -5,12 +5,23 @@ import org.openrndr.math.Vector3
import org.openrndr.math.Vector4 import org.openrndr.math.Vector4
import kotlin.math.abs import kotlin.math.abs
inline fun fbm(seed: Int, position: Vector4, crossinline noise: (Int, Double, Double, Double, Double) -> Double, inline fun fbm(
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5) = seed: Int, position: Vector4, crossinline noise: (Int, Double, Double, Double, Double) -> Double,
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5
) =
fbm(seed, position.x, position.y, position.z, position.w, noise, octaves, lacunarity, gain) fbm(seed, position.x, position.y, position.z, position.w, noise, octaves, lacunarity, gain)
inline fun fbm(seed: Int, x: Double, y: Double, z: Double, w: Double, crossinline noise: (Int, Double, Double, Double, Double) -> Double, inline fun fbm(
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): Double { seed: Int,
x: Double,
y: Double,
z: Double,
w: Double,
crossinline noise: (Int, Double, Double, Double, Double) -> Double,
octaves: Int = 8,
lacunarity: Double = 0.5,
gain: Double = 0.5
): Double {
var sum = noise(seed, x, y, z, w) var sum = noise(seed, x, y, z, w)
var amp = 1.0 var amp = 1.0
@@ -29,12 +40,16 @@ inline fun fbm(seed: Int, x: Double, y: Double, z: Double, w: Double, crossinlin
return sum return sum
} }
inline fun fbm(seed: Int, position: Vector3, crossinline noise: (Int, Double, Double, Double) -> Double, inline fun fbm(
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5) = seed: Int, position: Vector3, crossinline noise: (Int, Double, Double, Double) -> Double,
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5
) =
fbm(seed, position.x, position.y, position.z, noise, octaves, lacunarity, gain) fbm(seed, position.x, position.y, position.z, noise, octaves, lacunarity, gain)
inline fun fbm(seed: Int, x: Double, y: Double, z: Double, crossinline noise: (Int, Double, Double, Double) -> Double, inline fun fbm(
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): Double { seed: Int, x: Double, y: Double, z: Double, crossinline noise: (Int, Double, Double, Double) -> Double,
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5
): Double {
var sum = noise(seed, x, y, z) var sum = noise(seed, x, y, z)
var amp = 1.0 var amp = 1.0
@@ -51,12 +66,16 @@ inline fun fbm(seed: Int, x: Double, y: Double, z: Double, crossinline noise: (I
return sum return sum
} }
inline fun fbm(seed: Int, position: Vector2, crossinline noise: (Int, Double, Double) -> Double, inline fun fbm(
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5) = seed: Int, position: Vector2, crossinline noise: (Int, Double, Double) -> Double,
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5
) =
fbm(seed, position.x, position.y, noise, octaves, lacunarity, gain) fbm(seed, position.x, position.y, noise, octaves, lacunarity, gain)
inline fun fbm(seed: Int, x: Double, y: Double, crossinline noise: (Int, Double, Double) -> Double, inline fun fbm(
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): Double { seed: Int, x: Double, y: Double, crossinline noise: (Int, Double, Double) -> Double,
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5
): Double {
var sum = noise(seed, x, y) var sum = noise(seed, x, y)
var amp = 1.0 var amp = 1.0
@@ -71,8 +90,10 @@ inline fun fbm(seed: Int, x: Double, y: Double, crossinline noise: (Int, Double,
return sum return sum
} }
inline fun fbm(seed: Int, x: Double, crossinline noise: (Int, Double) -> Double, inline fun fbm(
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): Double { seed: Int, x: Double, crossinline noise: (Int, Double) -> Double,
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5
): Double {
var sum = noise(seed, x) var sum = noise(seed, x)
var amp = 1.0 var amp = 1.0
@@ -85,36 +106,69 @@ inline fun fbm(seed: Int, x: Double, crossinline noise: (Int, Double) -> Double,
return sum return sum
} }
inline fun fbmFunc1D(crossinline noise: (Int, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): (Int, Double) -> Double { inline fun fbmFunc1D(
crossinline noise: (Int, Double) -> Double,
octaves: Int = 8,
lacunarity: Double = 0.5,
gain: Double = 0.5
): (Int, Double) -> Double {
return { seed, x -> return { seed, x ->
fbm(seed, x, noise, octaves, lacunarity, gain) fbm(seed, x, noise, octaves, lacunarity, gain)
} }
} }
inline fun fbmFunc2D(crossinline noise: (Int, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): (Int, Double, Double) -> Double { inline fun fbmFunc2D(
crossinline noise: (Int, Double, Double) -> Double,
octaves: Int = 8,
lacunarity: Double = 0.5,
gain: Double = 0.5
): (Int, Double, Double) -> Double {
return { seed, x, y -> return { seed, x, y ->
fbm(seed, x, y, noise, octaves, lacunarity, gain) fbm(seed, x, y, noise, octaves, lacunarity, gain)
} }
} }
inline fun fbmFunc3D(crossinline noise: (Int, Double, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): (Int, Double, Double, Double) -> Double { inline fun fbmFunc3D(
crossinline noise: (Int, Double, Double, Double) -> Double,
octaves: Int = 8,
lacunarity: Double = 0.5,
gain: Double = 0.5
): (Int, Double, Double, Double) -> Double {
return { seed, x, y, z -> return { seed, x, y, z ->
fbm(seed, x, y, z, noise, octaves, lacunarity, gain) fbm(seed, x, y, z, noise, octaves, lacunarity, gain)
} }
} }
inline fun fbmFunc4D(crossinline noise: (Int, Double, Double, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): (Int, Double, Double, Double, Double) -> Double { inline fun fbmFunc4D(
crossinline noise: (Int, Double, Double, Double, Double) -> Double,
octaves: Int = 8,
lacunarity: Double = 0.5,
gain: Double = 0.5
): (Int, Double, Double, Double, Double) -> Double {
return { seed, x, y, z, w -> return { seed, x, y, z, w ->
fbm(seed, x, y, z, w, noise, octaves, lacunarity, gain) fbm(seed, x, y, z, w, noise, octaves, lacunarity, gain)
} }
} }
inline fun billow(seed: Int, position: Vector4, crossinline noise: (Int, Double, Double, Double, Double) -> Double, inline fun billow(
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5) = billow(seed, position.x, position.y, seed: Int, position: Vector4, crossinline noise: (Int, Double, Double, Double, Double) -> Double,
position.z, position.w, noise, octaves, lacunarity, gain) octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5
) = billow(
seed, position.x, position.y,
position.z, position.w, noise, octaves, lacunarity, gain
)
inline fun billow(seed: Int, x: Double, y: Double, z: Double, w: Double, crossinline noise: (Int, Double, Double, Double, Double) -> Double, inline fun billow(
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): Double { seed: Int,
x: Double,
y: Double,
z: Double,
w: Double,
crossinline noise: (Int, Double, Double, Double, Double) -> Double,
octaves: Int = 8,
lacunarity: Double = 0.5,
gain: Double = 0.5
): Double {
var sum = abs(noise(seed, x, y, z, w) * 2.0 - 1.0) var sum = abs(noise(seed, x, y, z, w) * 2.0 - 1.0)
var amp = 1.0 var amp = 1.0
@@ -133,12 +187,16 @@ inline fun billow(seed: Int, x: Double, y: Double, z: Double, w: Double, crossin
return sum return sum
} }
inline fun billow(seed: Int, position: Vector3, crossinline noise: (Int, Double, Double, Double) -> Double, inline fun billow(
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5) = seed: Int, position: Vector3, crossinline noise: (Int, Double, Double, Double) -> Double,
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5
) =
billow(seed, position.x, position.y, position.z, noise, octaves, lacunarity, gain) billow(seed, position.x, position.y, position.z, noise, octaves, lacunarity, gain)
inline fun billow(seed: Int, x: Double, y: Double, z: Double, crossinline noise: (Int, Double, Double, Double) -> Double, inline fun billow(
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): Double { seed: Int, x: Double, y: Double, z: Double, crossinline noise: (Int, Double, Double, Double) -> Double,
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5
): Double {
var sum = abs(noise(seed, x, y, z) * 2.0 - 1.0) var sum = abs(noise(seed, x, y, z) * 2.0 - 1.0)
var amp = 1.0 var amp = 1.0
@@ -155,12 +213,16 @@ inline fun billow(seed: Int, x: Double, y: Double, z: Double, crossinline noise:
return sum return sum
} }
inline fun billow(seed: Int, position: Vector2, crossinline noise: (Int, Double, Double) -> Double, inline fun billow(
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5) = seed: Int, position: Vector2, crossinline noise: (Int, Double, Double) -> Double,
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5
) =
billow(seed, position.x, position.y, noise, octaves, lacunarity, gain) billow(seed, position.x, position.y, noise, octaves, lacunarity, gain)
inline fun billow(seed: Int, x: Double, y: Double, crossinline noise: (Int, Double, Double) -> Double, inline fun billow(
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): Double { seed: Int, x: Double, y: Double, crossinline noise: (Int, Double, Double) -> Double,
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5
): Double {
var sum = abs(noise(seed, x, y) * 2.0 - 1.0) var sum = abs(noise(seed, x, y) * 2.0 - 1.0)
var amp = 1.0 var amp = 1.0
@@ -175,8 +237,10 @@ inline fun billow(seed: Int, x: Double, y: Double, crossinline noise: (Int, Doub
return sum return sum
} }
inline fun billow(seed: Int, x: Double, crossinline noise: (Int, Double) -> Double, inline fun billow(
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): Double { seed: Int, x: Double, crossinline noise: (Int, Double) -> Double,
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5
): Double {
var sum = abs(noise(seed, x) * 2.0 - 1.0) var sum = abs(noise(seed, x) * 2.0 - 1.0)
var amp = 1.0 var amp = 1.0
@@ -189,36 +253,67 @@ inline fun billow(seed: Int, x: Double, crossinline noise: (Int, Double) -> Doub
return sum return sum
} }
inline fun billowFunc1D(crossinline noise: (Int, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): (Int, Double) -> Double { inline fun billowFunc1D(
crossinline noise: (Int, Double) -> Double,
octaves: Int = 8,
lacunarity: Double = 0.5,
gain: Double = 0.5
): (Int, Double) -> Double {
return { seed, x -> return { seed, x ->
billow(seed, x, noise, octaves, lacunarity, gain) billow(seed, x, noise, octaves, lacunarity, gain)
} }
} }
inline fun billowFunc2D(crossinline noise: (Int, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): (Int, Double, Double) -> Double { inline fun billowFunc2D(
crossinline noise: (Int, Double, Double) -> Double,
octaves: Int = 8,
lacunarity: Double = 0.5,
gain: Double = 0.5
): (Int, Double, Double) -> Double {
return { seed, x, y -> return { seed, x, y ->
billow(seed, x, y, noise, octaves, lacunarity, gain) billow(seed, x, y, noise, octaves, lacunarity, gain)
} }
} }
inline fun billowFunc3D(crossinline noise: (Int, Double, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): (Int, Double, Double, Double) -> Double { inline fun billowFunc3D(
crossinline noise: (Int, Double, Double, Double) -> Double,
octaves: Int = 8,
lacunarity: Double = 0.5,
gain: Double = 0.5
): (Int, Double, Double, Double) -> Double {
return { seed, x, y, z -> return { seed, x, y, z ->
billow(seed, x, y, z, noise, octaves, lacunarity, gain) billow(seed, x, y, z, noise, octaves, lacunarity, gain)
} }
} }
inline fun billowFunc4D(crossinline noise: (Int, Double, Double, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): (Int, Double, Double, Double, Double) -> Double { inline fun billowFunc4D(
crossinline noise: (Int, Double, Double, Double, Double) -> Double,
octaves: Int = 8,
lacunarity: Double = 0.5,
gain: Double = 0.5
): (Int, Double, Double, Double, Double) -> Double {
return { seed, x, y, z, w -> return { seed, x, y, z, w ->
billow(seed, x, y, z, w, noise, octaves, lacunarity, gain) billow(seed, x, y, z, w, noise, octaves, lacunarity, gain)
} }
} }
inline fun rigid(seed: Int, position: Vector4, crossinline noise: (Int, Double, Double, Double, Double) -> Double, inline fun rigid(
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5) = seed: Int, position: Vector4, crossinline noise: (Int, Double, Double, Double, Double) -> Double,
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5
) =
rigid(seed, position.x, position.y, position.z, position.w, noise, octaves, lacunarity, gain) rigid(seed, position.x, position.y, position.z, position.w, noise, octaves, lacunarity, gain)
inline fun rigid(seed: Int, x: Double, y: Double, z: Double, w: Double, crossinline noise: (Int, Double, Double, Double, Double) -> Double, inline fun rigid(
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): Double { seed: Int,
x: Double,
y: Double,
z: Double,
w: Double,
crossinline noise: (Int, Double, Double, Double, Double) -> Double,
octaves: Int = 8,
lacunarity: Double = 0.5,
gain: Double = 0.5
): Double {
var sum = 1.0 - abs(noise(seed, x, y, z, w)) var sum = 1.0 - abs(noise(seed, x, y, z, w))
var amp = 1.0 var amp = 1.0
@@ -237,12 +332,16 @@ inline fun rigid(seed: Int, x: Double, y: Double, z: Double, w: Double, crossinl
return sum return sum
} }
inline fun rigid(seed: Int, position: Vector3, crossinline noise: (Int, Double, Double, Double) -> Double, inline fun rigid(
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5) = seed: Int, position: Vector3, crossinline noise: (Int, Double, Double, Double) -> Double,
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5
) =
rigid(seed, position.x, position.y, position.z, noise, octaves, lacunarity, gain) rigid(seed, position.x, position.y, position.z, noise, octaves, lacunarity, gain)
inline fun rigid(seed: Int, x: Double, y: Double, z: Double, crossinline noise: (Int, Double, Double, Double) -> Double, inline fun rigid(
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): Double { seed: Int, x: Double, y: Double, z: Double, crossinline noise: (Int, Double, Double, Double) -> Double,
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5
): Double {
var sum = 1.0 - abs(noise(seed, x, y, z)) var sum = 1.0 - abs(noise(seed, x, y, z))
var amp = 1.0 var amp = 1.0
@@ -259,12 +358,16 @@ inline fun rigid(seed: Int, x: Double, y: Double, z: Double, crossinline noise:
return sum return sum
} }
inline fun rigid(seed: Int, position: Vector2, crossinline noise: (Int, Double, Double) -> Double, inline fun rigid(
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5) = seed: Int, position: Vector2, crossinline noise: (Int, Double, Double) -> Double,
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5
) =
rigid(seed, position.x, position.y, noise, octaves, lacunarity, gain) rigid(seed, position.x, position.y, noise, octaves, lacunarity, gain)
inline fun rigid(seed: Int, x: Double, y: Double, crossinline noise: (Int, Double, Double) -> Double, inline fun rigid(
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): Double { seed: Int, x: Double, y: Double, crossinline noise: (Int, Double, Double) -> Double,
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5
): Double {
var sum = 1.0 - abs(noise(seed, x, y)) var sum = 1.0 - abs(noise(seed, x, y))
var amp = 1.0 var amp = 1.0
@@ -279,8 +382,10 @@ inline fun rigid(seed: Int, x: Double, y: Double, crossinline noise: (Int, Doubl
return sum return sum
} }
inline fun rigid(seed: Int, x: Double, crossinline noise: (Int, Double) -> Double, inline fun rigid(
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): Double { seed: Int, x: Double, crossinline noise: (Int, Double) -> Double,
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5
): Double {
var sum = 1.0 - abs(noise(seed, x)) var sum = 1.0 - abs(noise(seed, x))
var amp = 1.0 var amp = 1.0
@@ -293,26 +398,132 @@ inline fun rigid(seed: Int, x: Double, crossinline noise: (Int, Double) -> Doubl
return sum return sum
} }
inline fun rigidFunc1D(crossinline noise: (Int, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): (Int, Double) -> Double { inline fun rigidFunc1D(
crossinline noise: (Int, Double) -> Double,
octaves: Int = 8,
lacunarity: Double = 0.5,
gain: Double = 0.5
): (Int, Double) -> Double {
return { seed, x -> return { seed, x ->
rigid(seed, x, noise, octaves, lacunarity, gain) rigid(seed, x, noise, octaves, lacunarity, gain)
} }
} }
inline fun rigidFunc2D(crossinline noise: (Int, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): (Int, Double, Double) -> Double { inline fun rigidFunc2D(
crossinline noise: (Int, Double, Double) -> Double,
octaves: Int = 8,
lacunarity: Double = 0.5,
gain: Double = 0.5
): (Int, Double, Double) -> Double {
return { seed, x, y -> return { seed, x, y ->
rigid(seed, x, y, noise, octaves, lacunarity, gain) rigid(seed, x, y, noise, octaves, lacunarity, gain)
} }
} }
inline fun rigidFunc3D(crossinline noise: (Int, Double, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): (Int, Double, Double, Double) -> Double { inline fun rigidFunc3D(
crossinline noise: (Int, Double, Double, Double) -> Double,
octaves: Int = 8,
lacunarity: Double = 0.5,
gain: Double = 0.5
): (Int, Double, Double, Double) -> Double {
return { seed, x, y, z -> return { seed, x, y, z ->
rigid(seed, x, y, z, noise, octaves, lacunarity, gain) rigid(seed, x, y, z, noise, octaves, lacunarity, gain)
} }
} }
inline fun rigidFunc4D(crossinline noise: (Int, Double, Double, Double, Double) -> Double, octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): (Int, Double, Double, Double, Double) -> Double { inline fun rigidFunc4D(
crossinline noise: (Int, Double, Double, Double, Double) -> Double,
octaves: Int = 8,
lacunarity: Double = 0.5,
gain: Double = 0.5
): (Int, Double, Double, Double, Double) -> Double {
return { seed, x, y, z, w -> return { seed, x, y, z, w ->
rigid(seed, x, y, z, w, noise, octaves, lacunarity, gain) rigid(seed, x, y, z, w, noise, octaves, lacunarity, gain)
} }
} }
// functional composition tools
fun ((Int, Double) -> Double).fbm(
octaves: Int = 8,
lacunarity: Double = 0.5,
gain: Double = 0.5
): (Int, Double) -> Double =
fbmFunc1D(this, octaves, lacunarity, gain)
fun ((Int, Double, Double) -> Double).fbm(
octaves: Int = 8,
lacunarity: Double = 0.5,
gain: Double = 0.5
): (Int, Double, Double) -> Double =
fbmFunc2D(this, octaves, lacunarity, gain)
fun ((Int, Double, Double, Double) -> Double).fbm(
octaves: Int = 8,
lacunarity: Double = 0.5,
gain: Double = 0.5
): (Int, Double, Double, Double) -> Double =
fbmFunc3D(this, octaves, lacunarity, gain)
fun ((Int, Double, Double, Double, Double) -> Double).fbm(
octaves: Int = 8,
lacunarity: Double = 0.5,
gain: Double = 0.5
): (Int, Double, Double, Double, Double) -> Double =
fbmFunc4D(this, octaves, lacunarity, gain)
fun ((Int, Double) -> Double).billow(
octaves: Int = 8,
lacunarity: Double = 0.5,
gain: Double = 0.5
): (Int, Double) -> Double =
billowFunc1D(this, octaves, lacunarity, gain)
fun ((Int, Double, Double) -> Double).billow(
octaves: Int = 8,
lacunarity: Double = 0.5,
gain: Double = 0.5
): (Int, Double, Double) -> Double =
billowFunc2D(this, octaves, lacunarity, gain)
fun ((Int, Double, Double, Double) -> Double).billow(
octaves: Int = 8,
lacunarity: Double = 0.5,
gain: Double = 0.5
): (Int, Double, Double, Double) -> Double =
billowFunc3D(this, octaves, lacunarity, gain)
fun ((Int, Double, Double, Double, Double) -> Double).billow(
octaves: Int = 8,
lacunarity: Double = 0.5,
gain: Double = 0.5
): (Int, Double, Double, Double, Double) -> Double =
billowFunc4D(this, octaves, lacunarity, gain)
fun ((Int, Double) -> Double).rigid(
octaves: Int = 8,
lacunarity: Double = 0.5,
gain: Double = 0.5
): (Int, Double) -> Double =
rigidFunc1D(this, octaves, lacunarity, gain)
fun ((Int, Double, Double) -> Double).rigid(
octaves: Int = 8,
lacunarity: Double = 0.5,
gain: Double = 0.5
): (Int, Double, Double) -> Double =
rigidFunc2D(this, octaves, lacunarity, gain)
fun ((Int, Double, Double, Double) -> Double).rigid(
octaves: Int = 8,
lacunarity: Double = 0.5,
gain: Double = 0.5
): (Int, Double, Double, Double) -> Double =
rigidFunc3D(this, octaves, lacunarity, gain)
fun ((Int, Double, Double, Double, Double) -> Double).rigid(
octaves: Int = 8,
lacunarity: Double = 0.5,
gain: Double = 0.5
): (Int, Double, Double, Double, Double) -> Double =
rigidFunc4D(this, octaves, lacunarity, gain)

View File

@@ -0,0 +1,96 @@
package org.openrndr.extra.noise
import org.openrndr.math.Vector2
import org.openrndr.math.Vector3
import org.openrndr.math.Vector4
import kotlin.jvm.JvmName
fun ((Double) -> Double).withSeedAsOffset(offset: Double): (Int, Double) -> Double = { seed, x ->
this(x + seed * offset)
}
fun ((Int, Double) -> Double).withFixedSeed(seed: Int): (Double) -> Double = { x -> this(seed, x) }
fun ((Int, Double) -> Double).scaleBiasOutput(
scale: Double = 1.0,
bias: Double = 0.0
): (Int, Double) -> Double = { seed, x ->
this(seed, x) * scale + bias
}
fun ((Int, Double) -> Double).mapOutput(map: (Double)->Double): (Int, Double) -> Double = { seed, x ->
map(this(seed, x))
}
fun ((Int, Double, Double) -> Double).withVector2Input(): (Int, Vector2) -> Double = { seed, v ->
this(seed, v.x, v.y)
}
@JvmName("scaleBiasVector2")
fun ((Int, Vector2) -> Double).scaleBiasOutput(
scale: Double = 1.0,
bias: Double = 0.0
): (Int, Vector2) -> Double = { seed, v ->
this(seed, v) * scale + bias
}
fun ((Int, Double, Double) -> Double).scaleBiasOutput(
scale: Double = 1.0,
bias: Double = 0.0
): (Int, Double, Double) -> Double = { seed, x, y ->
this(seed, x, y) * scale + bias
}
fun ((Int, Vector2) -> Double).withScalarInput(): (Int, Double, Double) -> Double = { seed, x, y ->
this(seed, Vector2(x, y))
}
fun ((Int, Double, Double, Double) -> Double).withVector3Input(): (Int, Vector3) -> Double = { seed, v ->
this(seed, v.x, v.y, v.z)
}
fun ((Int, Vector3) -> Double).withScalarInput(): (Int, Double, Double, Double) -> Double = { seed, x, y, z ->
this(seed, Vector3(x, y, z))
}
fun ((Int, Double, Double, Double, Double) -> Double).withVector4Input(): (Int, Vector4) -> Double = { seed, v ->
this(seed, v.x, v.y, v.z, v.w)
}
@JvmName("perturb1")
fun ((Int, Double) -> Double).perturb(distort: (Double) -> Double): (Int, Double) -> Double =
{ seed, x ->
this(seed, distort(x))
}
@JvmName("perturb2v")
inline fun ((Int, Vector2) -> Double).perturb(crossinline distort: (Vector2) -> Vector2): (Int, Vector2) -> Double =
{ seed, v ->
this(seed, distort(v))
}
@JvmName("perturb2ds")
inline fun ((Int, Double, Double) -> Double).perturb(crossinline distort: (Vector2) -> Vector2): (Int, Double, Double) -> Double =
{ seed, x, y ->
val d = distort(Vector2(x, y))
this(seed, d.x, d.y)
}
@JvmName("perturb3")
inline fun ((Int, Vector3) -> Double).perturb(crossinline distort: (Vector3) -> Vector3): (Int, Vector3) -> Double =
{ seed, v ->
this(seed, distort(v))
}
@JvmName("perturb3ds")
inline fun ((Int, Double, Double, Double) -> Double).perturb(crossinline distort: (Vector3) -> Vector3): (Int, Double, Double, Double) -> Double =
{ seed, x, y, z ->
val d = distort(Vector3(x, y, z))
this(seed, d.x, d.y, d.z)
}
@JvmName("perturb4")
inline fun ((Int, Vector4) -> Double).perturb(crossinline distort: (Vector4) -> Vector4): (Int, Vector4) -> Double =
{ seed, v ->
this(seed, distort(v))
}

View File

@@ -7,3 +7,5 @@ fun perlinHermite(seed: Int, x: Double) = perlin(seed, x, ::hermite)
inline fun perlin(seed: Int, x: Double, crossinline interpolator: (Double) -> Double): Double = inline fun perlin(seed: Int, x: Double, crossinline interpolator: (Double) -> Double): Double =
perlin(seed, x, 0.0, interpolator) perlin(seed, x, 0.0, interpolator)
val perlin1D: (Int, Double) -> Double = ::perlin

View File

@@ -32,3 +32,5 @@ inline fun perlin(seed: Int, x: Double, y: Double, crossinline interpolator: (Do
return mix(xf0, xf1, ys) return mix(xf0, xf1, ys)
} }
val perlin2D: (Int, Double, Double) -> Double = ::perlin

View File

@@ -40,3 +40,5 @@ inline fun perlin(seed: Int, x: Double, y: Double, z: Double, crossinline interp
return mix(yf0, yf1, zs) return mix(yf0, yf1, zs)
} }
val perlin3D: (Int, Double, Double, Double) -> Double = ::perlinLinear

View File

@@ -0,0 +1,77 @@
package org.openrndr.extra.noise
import org.openrndr.math.Polar
import org.openrndr.math.Vector2
/**
* Polar coordinate front-end for 2D noise functions
*/
fun polarFunc(
noise: (Int, Double, Double) -> Double,
origin: Vector2 = Vector2.ZERO,
): (seed: Int, polar: Polar) -> Double {
return { seed, polar ->
val c = polar.cartesian + origin
noise(seed, c.x, c.y)
}
}
/**
* Polar coordinate front-end for 2D noise functions
*/
fun fixedRadiusPolarFunc(
noise: (Int, Double, Double) -> Double,
radius: Double,
origin: Vector2 = Vector2.ZERO,
): (seed: Int, angleInDegrees: Double) -> Double {
return { seed, angleInDegrees ->
val c = Polar(angleInDegrees, radius).cartesian + origin
noise(seed, c.x, c.y)
}
}
/**
* Polar coordinate front-end for 2D noise functions with variable offset
*/
fun polarOffsetFunc(
noise: (Int, Double, Double) -> Double,
origin: Vector2 = Vector2.ZERO,
): (seed: Int, polar: Polar, offset: Vector2) -> Double {
return { seed, polar, offset ->
val c = polar.cartesian + origin + offset
noise(seed, c.x, c.y)
}
}
fun ((Int, Double, Double) -> Double).withPolarInput(origin: Vector2 = Vector2.ZERO): (Int, Polar) -> Double =
polarFunc(this, origin)
fun ((Int, Vector2) -> Double).withPolarInput(origin: Vector2 = Vector2.ZERO): (Int, Polar) -> Double =
polarFunc(this.withScalarInput(), origin)
fun ((Int, Double, Double) -> Double).withPolarOffsetInput(origin: Vector2 = Vector2.ZERO): (Int, Polar, Vector2) -> Double =
polarOffsetFunc(this, origin)
fun ((Int, Vector2) -> Double).withPolarOffsetInput(origin: Vector2 = Vector2.ZERO): (Int, Polar, Vector2) -> Double =
polarOffsetFunc(this.withScalarInput(), origin)
fun ((Int, Double, Double) -> Double).fixedRadiusPolar(
radius: Double,
origin: Vector2 = Vector2.ZERO
): (Int, Double) -> Double =
fixedRadiusPolarFunc(this, radius, origin)
private fun example() {
val polarFbmSimplex = polarFunc(noise = fbmFunc2D(noise = ::simplex))
val polarBillowPerlin = polarFunc(noise = billowFunc2D(noise = ::perlin))
val polarFbmSimplexAlt = fbmFunc2D(noise = ::simplex).withPolarInput()
val polarFbm = simplex2D.fbm().withPolarInput()
}

View File

@@ -8,6 +8,8 @@ private const val G2 = (3.0 - SQRT3) / 6.0
fun simplex(seed: Int, position: Vector2): Double = simplex(seed, position.x, position.y) fun simplex(seed: Int, position: Vector2): Double = simplex(seed, position.x, position.y)
//fun simplex2D(seed:Int, x:Double, y:Double) = simplex(seed, x, y)
fun simplex(seed: Int, x: Double, y: Double): Double { fun simplex(seed: Int, x: Double, y: Double): Double {
var t = (x + y) * F2 var t = (x + y) * F2
val i = (x + t).fastFloor() val i = (x + t).fastFloor()
@@ -63,5 +65,12 @@ fun simplex(seed: Int, x: Double, y: Double): Double {
return 50.0 * (n0 + n1 + n2) return 50.0 * (n0 + n1 + n2)
} }
fun Vector2.Companion.simplex(seed: Int, x: Double): Vector2 = Vector2(simplex(seed, x, 0.0, 0.0, 0.0), val simplex1D: (Int, Double) -> Double = ::simplex
simplex(seed, 0.0, x + 31.3383, 0.0, 0.0)) val simplex2D: (Int, Double, Double) -> Double = ::simplex
val simplex3D: (Int, Double, Double, Double) -> Double = ::simplex
val simplex4D: (Int, Double, Double, Double) -> Double = ::simplex
fun Vector2.Companion.simplex(seed: Int, x: Double): Vector2 = Vector2(
simplex(seed, x, 0.0, 0.0, 0.0),
simplex(seed, 0.0, x + 31.3383, 0.0, 0.0)
)

View File

@@ -6,3 +6,7 @@ fun valueHermite(seed: Int, x: Double) = value(seed, x, ::hermite)
inline fun value(seed: Int, x: Double, crossinline interpolation: (Double) -> Double = ::linear): Double = inline fun value(seed: Int, x: Double, crossinline interpolation: (Double) -> Double = ::linear): Double =
value(seed, x, 0.0, interpolation) value(seed, x, 0.0, interpolation)
val valueLinear1D: (Int, Double) -> Double = ::valueLinear
val valueQuintic1D: (Int, Double) -> Double = ::valueQuintic
val valueHermite1D: (Int, Double) -> Double = ::valueHermite

View File

@@ -30,3 +30,7 @@ inline fun value(seed: Int, x: Double, y: Double, crossinline interpolation: (Do
return mix(xf0, xf1, ys) return mix(xf0, xf1, ys)
} }
val valueLinear2D: (Int, Double, Double) -> Double = ::valueLinear
val valueQuintic2D: (Int, Double, Double) -> Double = ::valueQuintic
val valueHermite2D: (Int, Double, Double) -> Double = ::valueHermite

View File

@@ -39,3 +39,7 @@ inline fun value(seed: Int, x: Double, y: Double, z: Double, crossinline interpo
return mix(yf0, yf1, zs) return mix(yf0, yf1, zs)
} }
val valueLinear3D: (Int, Double, Double, Double) -> Double = ::valueLinear
val valueQuintic3D: (Int, Double, Double, Double) -> Double = ::valueQuintic
val valueHermite3D: (Int, Double, Double, Double) -> Double = ::valueHermite

View File

@@ -0,0 +1,14 @@
package org.openrndr.extra.noise
import org.openrndr.math.Vector2
fun ((Int, Double) -> Double).vector2(): (seed: Int, x: Double) -> Vector2 {
val ref = this
return { seed:Int, x:Double ->
Vector2(ref(-seed, x), ref(seed, -x))
}
}
private fun exampleVector() {
::simplex2D
}