Add 1d noise versions, Gaussian noise, noise gradients, 4D fractal functions
This commit is contained in:
@@ -1,128 +1,161 @@
|
|||||||
# orx-noise
|
# orx-noise
|
||||||
|
|
||||||
A collection of noisy functions
|
A collection of noisy functions
|
||||||
|
|
||||||
## Uniform random numbers
|
## Uniform random numbers
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
val sua = Double.uniform()
|
val sua = Double.uniform()
|
||||||
val sub = Double.uniform(-1.0, 1.0)
|
val sub = Double.uniform(-1.0, 1.0)
|
||||||
|
|
||||||
val v2ua = Vector2.uniform()
|
val v2ua = Vector2.uniform()
|
||||||
val v2ub = Vector2.uniform(-1.0, 1.0)
|
val v2ub = Vector2.uniform(-1.0, 1.0)
|
||||||
val v2uc = Vector2.uniform(Vector2(0.0, 0.0), Vector2(1.0, 1.0))
|
val v2uc = Vector2.uniform(Vector2(0.0, 0.0), Vector2(1.0, 1.0))
|
||||||
val v2ur = Vector2.uniformRing(0.5, 1.0)
|
val v2ur = Vector2.uniformRing(0.5, 1.0)
|
||||||
|
|
||||||
val v3ua = Vector3.uniform()
|
val v3ua = Vector3.uniform()
|
||||||
val v3ub = Vector3.uniform(-1.0, 1.0)
|
val v3ub = Vector3.uniform(-1.0, 1.0)
|
||||||
val v3uc = Vector3.uniform(Vector3(0.0, 0.0, 0.0), Vector3(1.0, 1.0, 1.0))
|
val v3uc = Vector3.uniform(Vector3(0.0, 0.0, 0.0), Vector3(1.0, 1.0, 1.0))
|
||||||
val v3ur = Vector3.uniformRing(0.5, 1.0)
|
val v3ur = Vector3.uniformRing(0.5, 1.0)
|
||||||
|
|
||||||
val v4ua = Vector4.uniform()
|
val v4ua = Vector4.uniform()
|
||||||
val v4ub = Vector4.uniform(-1.0, 1.0)
|
val v4ub = Vector4.uniform(-1.0, 1.0)
|
||||||
val v4uc = Vector4.uniform(Vector4(0.0, 0.0, 0.0, 0.0), Vector4(1.0, 1.0, 1.0, 1.0))
|
val v4uc = Vector4.uniform(Vector4(0.0, 0.0, 0.0, 0.0), Vector4(1.0, 1.0, 1.0, 1.0))
|
||||||
val v4ur = Vector4.uniformRing(0.5, 1.0)
|
val v4ur = Vector4.uniformRing(0.5, 1.0)
|
||||||
|
|
||||||
val ringSamples = List(500) { Vector2.uniformRing() }
|
val ringSamples = List(500) { Vector2.uniformRing() }
|
||||||
```
|
```
|
||||||
|
|
||||||
## 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.
|
||||||
|
|
||||||
### Perlin noise
|
### Perlin noise
|
||||||
```
|
```
|
||||||
// -- 2d
|
// -- 1d
|
||||||
val v0 = perlinLinear(seed, x, y)
|
val v0 = perlinLinear(seed, x)
|
||||||
val v1 = perlinQuintic(seed, x, y)
|
val v1 = perlinQuintic(seed, x)
|
||||||
val v2 = perlinHermite(seed, x, y)
|
val v2 = perlinHermite(seed, x)
|
||||||
|
|
||||||
// -- 3d
|
// -- 2d
|
||||||
val v3 = perlinLinear(seed, x, y, z)
|
val v3 = perlinLinear(seed, x, y)
|
||||||
val v4 = perlinQuintic(seed, x, y, z)
|
val v4 = perlinQuintic(seed, x, y)
|
||||||
val v5 = perlinHermite(seed, x, y, z)
|
val v5 = perlinHermite(seed, x, y)
|
||||||
```
|
|
||||||
|
// -- 3d
|
||||||
### Value noise
|
val v6 = perlinLinear(seed, x, y, z)
|
||||||
```
|
val v7 = perlinQuintic(seed, x, y, z)
|
||||||
// -- 2d
|
val v8 = perlinHermite(seed, x, y, z)
|
||||||
val v0 = valueLinear(seed, x, y)
|
```
|
||||||
val v1 = valueQuintic(seed, x, y)
|
|
||||||
val v2 = valueHermite(seed, x, y)
|
### Value noise
|
||||||
|
```
|
||||||
// -- 3d
|
// -- 1d
|
||||||
val v3 = valueLinear(seed, x, y, z)
|
val v0 = valueLinear(seed, x)
|
||||||
val v4 = valueQuintic(seed, x, y, z)
|
val v1 = valueQuintic(seed, x)
|
||||||
val v5 = valueHermite(seed, x, y ,z)
|
val v2 = valueHermite(seed, x)
|
||||||
```
|
|
||||||
|
// -- 2d
|
||||||
### Simplex noise
|
val v2 = valueLinear(seed, x, y)
|
||||||
```
|
val v3 = valueQuintic(seed, x, y)
|
||||||
// -- 2d
|
val v4 = valueHermite(seed, x, y)
|
||||||
val v0 = simplexLinear(seed, x, y)
|
|
||||||
val v1 = simplexQuintic(seed, x, y)
|
// -- 3d
|
||||||
val v2 = simplexHermite(seed, x, y)
|
val v5 = valueLinear(seed, x, y, z)
|
||||||
|
val v6 = valueQuintic(seed, x, y, z)
|
||||||
// -- 3d
|
val v7 = valueHermite(seed, x, y ,z)
|
||||||
val v3 = simplexLinear(seed, x, y, z)
|
```
|
||||||
val v4 = simplexQuintic(seed, x, y, z)
|
|
||||||
val v5 = simplexHermite(seed, x, y ,z)
|
### Simplex noise
|
||||||
|
```
|
||||||
// -- 4d
|
// -- 1d
|
||||||
val v6 = simplexLinear(seed, x, y, z, w)
|
val v0 = simplex(seed, x)
|
||||||
val v7 = simplexQuintic(seed, x, y, z, w)
|
|
||||||
val v8 = simplexHermite(seed, x, y, z, w)
|
// -- 2d
|
||||||
```
|
val v1 = simplex(seed, x, y)
|
||||||
|
|
||||||
### Cubic noise
|
// -- 3d
|
||||||
```
|
val v2 = simplex(seed, x, y, z)
|
||||||
// -- 2d
|
|
||||||
val v0 = cubicLinear(seed, x, y)
|
// -- 4d
|
||||||
val v1 = cubicQuintic(seed, x, y)
|
val v3 = simplex(seed, x, y, z, w)
|
||||||
val v2 = cubicHermite(seed, x, y)
|
```
|
||||||
|
|
||||||
// -- 3d
|
### Cubic noise
|
||||||
val v3 = cubicLinear(seed, x, y, z)
|
```
|
||||||
val v4 = cubicQuintic(seed, x, y, z)
|
// -- 1d
|
||||||
val v5 = cubicHermite(seed, x, y ,z)
|
val v0 = cubic(seed, x, y)
|
||||||
```
|
val v1 = cubicQuintic(seed, x, y)
|
||||||
|
val v2 = cubicHermite(seed, x, y)
|
||||||
### Fractal noise
|
|
||||||
|
// -- 2d
|
||||||
The library provides 3 functions with which fractal noise can be composed.
|
val v0 = cubic(seed, x, y)
|
||||||
|
val v1 = cubicQuintic(seed, x, y)
|
||||||
#### Fractal brownian motion (FBM)
|
val v2 = cubicHermite(seed, x, y)
|
||||||
|
|
||||||
```
|
// -- 3d
|
||||||
val v0 = fbm(seed, x, y, ::perlinLinear, octaves, lacunarity, gain)
|
val v3 = cubic(seed, x, y, z)
|
||||||
val v1 = fbm(seed, x, y, ::simplexLinear, octaves, lacunarity, gain)
|
val v4 = cubicQuintic(seed, x, y, z)
|
||||||
val v2 = fbm(seed, x, y, ::valueLinear, octaves, lacunarity, gain)
|
val v5 = cubicHermite(seed, x, y ,z)
|
||||||
|
```
|
||||||
val v3 = fbm(seed, x, y, z, ::perlinLinear, octaves, lacunarity, gain)
|
|
||||||
val v4 = fbm(seed, x, y, z, ::simplexLinear, octaves, lacunarity, gain)
|
### Fractal noise
|
||||||
val v5 = fbm(seed, x, y, z, ::valueLinear, octaves, lacunarity, gain)
|
|
||||||
```
|
The library provides 3 functions with which fractal noise can be composed.
|
||||||
|
|
||||||
#### Rigid
|
#### Fractal brownian motion (FBM)
|
||||||
|
|
||||||
```
|
```
|
||||||
val v0 = rigid(seed, x, y, ::perlinLinear, octaves, lacunarity, gain)
|
// 1d
|
||||||
val v1 = rigid(seed, x, y, ::simplexLinear, octaves, lacunarity, gain)
|
val v0 = fbm(seed, x, ::perlinLinear, octaves, lacunarity, gain)
|
||||||
val v2 = rigid(seed, x, y, ::valueLinear, octaves, lacunarity, gain)
|
val v1 = fbm(seed, x, ::simplexLinear, octaves, lacunarity, gain)
|
||||||
|
val v2 = fbm(seed, x, ::valueLinear, octaves, lacunarity, gain)
|
||||||
val v3 = rigid(seed, x, y, z, ::perlinLinear, octaves, lacunarity, gain)
|
|
||||||
val v4 = rigid(seed, x, y, z, ::simplexLinear, octaves, lacunarity, gain)
|
// 2d
|
||||||
val v5 = rigid(seed, x, y, z, ::valueLinear, octaves, lacunarity, gain)
|
val v3 = fbm(seed, x, y, ::perlinLinear, octaves, lacunarity, gain)
|
||||||
```
|
val v4 = fbm(seed, x, y, ::simplexLinear, octaves, lacunarity, gain)
|
||||||
|
val v5 = fbm(seed, x, y, ::valueLinear, octaves, lacunarity, gain)
|
||||||
#### Billow
|
|
||||||
|
// 3d
|
||||||
```
|
val v6 = fbm(seed, x, y, z, ::perlinLinear, octaves, lacunarity, gain)
|
||||||
val v0 = billow(seed, x, y, ::perlinLinear, octaves, lacunarity, gain)
|
val v7 = fbm(seed, x, y, z, ::simplexLinear, octaves, lacunarity, gain)
|
||||||
val v1 = billow(seed, x, y, ::perlinLinear, octaves, lacunarity, gain)
|
val v8 = fbm(seed, x, y, z, ::valueLinear, octaves, lacunarity, gain)
|
||||||
val v2 = billow(seed, x, y, ::perlinLinear, octaves, lacunarity, gain)
|
```
|
||||||
|
|
||||||
val v3 = billow(seed, x, y, z, ::perlinLinear, octaves, lacunarity, gain)
|
#### Rigid
|
||||||
val v4 = billow(seed, x, y, z, ::perlinLinear, octaves, lacunarity, gain)
|
|
||||||
val v5 = billow(seed, x, y, z, ::perlinLinear, octaves, lacunarity, gain)
|
```
|
||||||
```
|
// 1d
|
||||||
|
val v0 = rigid(seed, x, ::perlinLinear, octaves, lacunarity, gain)
|
||||||
|
val v1 = rigid(seed, x, ::simplexLinear, octaves, lacunarity, gain)
|
||||||
|
val v2 = rigid(seed, x, ::valueLinear, octaves, lacunarity, gain)
|
||||||
|
|
||||||
|
// 2d
|
||||||
|
val v2 = rigid(seed, x, y, ::perlinLinear, octaves, lacunarity, gain)
|
||||||
|
val v3 = rigid(seed, x, y, ::simplexLinear, octaves, lacunarity, gain)
|
||||||
|
val v4 = rigid(seed, x, y, ::valueLinear, octaves, lacunarity, gain)
|
||||||
|
|
||||||
|
// 3d
|
||||||
|
val v3 = rigid(seed, x, y, z, ::perlinLinear, octaves, lacunarity, gain)
|
||||||
|
val v4 = rigid(seed, x, y, z, ::simplexLinear, octaves, lacunarity, gain)
|
||||||
|
val v5 = rigid(seed, x, y, z, ::valueLinear, octaves, lacunarity, gain)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Billow
|
||||||
|
|
||||||
|
```
|
||||||
|
// 1d
|
||||||
|
val v0 = billow(seed, x, ::perlinLinear, octaves, lacunarity, gain)
|
||||||
|
val v1 = billow(seed, x, ::perlinLinear, octaves, lacunarity, gain)
|
||||||
|
val v2 = billow(seed, x, ::perlinLinear, octaves, lacunarity, gain)
|
||||||
|
|
||||||
|
// 2d
|
||||||
|
val v3 = billow(seed, x, y, ::perlinLinear, octaves, lacunarity, gain)
|
||||||
|
val v4 = billow(seed, x, y, ::perlinLinear, octaves, lacunarity, gain)
|
||||||
|
val v5 = billow(seed, x, y, ::perlinLinear, octaves, lacunarity, gain)
|
||||||
|
|
||||||
|
// 3d
|
||||||
|
val v6 = billow(seed, x, y, z, ::perlinLinear, octaves, lacunarity, gain)
|
||||||
|
val v7 = billow(seed, x, y, z, ::perlinLinear, octaves, lacunarity, gain)
|
||||||
|
val v8 = billow(seed, x, y, z, ::perlinLinear, octaves, lacunarity, gain)
|
||||||
|
```
|
||||||
|
|||||||
10
orx-noise/src/main/kotlin/CubicNoise1D.kt
Normal file
10
orx-noise/src/main/kotlin/CubicNoise1D.kt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package org.openrndr.extra.noise
|
||||||
|
|
||||||
|
fun cubicLinear(seed: Int, x: Double) = cubic(seed, x, ::linear)
|
||||||
|
fun cubicQuintic(seed: Int, x: Double) = cubic(seed, x, ::quintic)
|
||||||
|
fun cubicHermite(seed: Int, x: Double) = cubic(seed, x, ::hermite)
|
||||||
|
|
||||||
|
|
||||||
|
fun cubic(seed: Int, x: Double, interpolator: (Double) -> Double = ::linear): Double {
|
||||||
|
return cubic(seed, x, 0.0, interpolator)
|
||||||
|
}
|
||||||
@@ -1,5 +1,28 @@
|
|||||||
package org.openrndr.extra.noise
|
package org.openrndr.extra.noise
|
||||||
|
|
||||||
|
import kotlin.math.abs
|
||||||
|
|
||||||
|
|
||||||
|
inline fun fbm(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 amp = 1.0
|
||||||
|
|
||||||
|
var x = x
|
||||||
|
var y = y
|
||||||
|
var z = z
|
||||||
|
var w = w
|
||||||
|
for (i in 1 until octaves) {
|
||||||
|
x *= lacunarity
|
||||||
|
y *= lacunarity
|
||||||
|
z *= lacunarity
|
||||||
|
w *= lacunarity
|
||||||
|
amp *= gain
|
||||||
|
sum += noise(seed + i, x, y, z, w) * amp
|
||||||
|
}
|
||||||
|
return sum
|
||||||
|
}
|
||||||
|
|
||||||
inline fun fbm(seed: Int, x: Double, y: Double, z: Double, crossinline noise: (Int, Double, Double, Double) -> Double,
|
inline fun fbm(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 {
|
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)
|
||||||
@@ -18,7 +41,6 @@ inline fun fbm(seed: Int, x: Double, y: Double, z: Double, crossinline noise: (I
|
|||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline fun fbm(seed: Int, x: Double, y: Double, crossinline noise: (Int, Double, Double) -> Double,
|
inline fun fbm(seed: Int, x: Double, y: Double, crossinline noise: (Int, Double, Double) -> Double,
|
||||||
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): 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)
|
||||||
@@ -35,6 +57,66 @@ 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,
|
||||||
|
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): Double {
|
||||||
|
var sum = noise(seed, x)
|
||||||
|
var amp = 1.0
|
||||||
|
|
||||||
|
var x = x
|
||||||
|
for (i in 1 until octaves) {
|
||||||
|
x *= lacunarity
|
||||||
|
amp *= gain
|
||||||
|
sum += noise(seed + i, x) * amp
|
||||||
|
}
|
||||||
|
return sum
|
||||||
|
}
|
||||||
|
|
||||||
|
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 ->
|
||||||
|
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 {
|
||||||
|
return { seed, x, y ->
|
||||||
|
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 {
|
||||||
|
return { seed, x, y, z ->
|
||||||
|
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 {
|
||||||
|
return { seed, x, y, z, w ->
|
||||||
|
fbm(seed, x, y, z, 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,
|
||||||
|
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): Double {
|
||||||
|
var sum = Math.abs(noise(seed, x, y, z, w) * 2.0 - 1.0)
|
||||||
|
var amp = 1.0
|
||||||
|
|
||||||
|
var x = x
|
||||||
|
var y = y
|
||||||
|
var z = z
|
||||||
|
var w = w
|
||||||
|
for (i in 1 until octaves) {
|
||||||
|
x *= lacunarity
|
||||||
|
y *= lacunarity
|
||||||
|
z *= lacunarity
|
||||||
|
w *= lacunarity
|
||||||
|
amp *= gain
|
||||||
|
sum += Math.abs(noise(seed + i, x, y, z, w) * 2.0 - 1.0) * amp
|
||||||
|
}
|
||||||
|
return sum
|
||||||
|
}
|
||||||
|
|
||||||
inline fun billow(seed: Int, x: Double, y: Double, z: Double, crossinline noise: (Int, Double, Double, Double) -> Double,
|
inline fun billow(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 {
|
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): Double {
|
||||||
var sum = Math.abs(noise(seed, x, y, z) * 2.0 - 1.0)
|
var sum = Math.abs(noise(seed, x, y, z) * 2.0 - 1.0)
|
||||||
@@ -55,7 +137,7 @@ inline fun billow(seed: Int, x: Double, y: Double, z: Double, crossinline noise:
|
|||||||
|
|
||||||
inline fun billow(seed: Int, x: Double, y: Double, crossinline noise: (Int, Double, Double) -> Double,
|
inline fun billow(seed: Int, x: Double, y: Double, crossinline noise: (Int, Double, Double) -> Double,
|
||||||
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): Double {
|
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): Double {
|
||||||
var sum = Math.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
|
||||||
|
|
||||||
var x = x
|
var x = x
|
||||||
@@ -64,7 +146,83 @@ inline fun billow(seed: Int, x: Double, y: Double, crossinline noise: (Int, Doub
|
|||||||
x *= lacunarity
|
x *= lacunarity
|
||||||
y *= lacunarity
|
y *= lacunarity
|
||||||
amp *= gain
|
amp *= gain
|
||||||
sum += Math.abs(noise(seed + i, x, y) * 2.0 - 1.0) * amp
|
sum += abs(noise(seed + i, x, y) * 2.0 - 1.0) * amp
|
||||||
|
}
|
||||||
|
return sum
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun billow(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 amp = 1.0
|
||||||
|
|
||||||
|
var x = x
|
||||||
|
for (i in 1 until octaves) {
|
||||||
|
x *= lacunarity
|
||||||
|
amp *= gain
|
||||||
|
sum += abs(noise(seed + i, x) * 2.0 - 1.0) * amp
|
||||||
|
}
|
||||||
|
return sum
|
||||||
|
}
|
||||||
|
|
||||||
|
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 ->
|
||||||
|
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 {
|
||||||
|
return { seed, x, y ->
|
||||||
|
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 {
|
||||||
|
return { seed, x, y, z ->
|
||||||
|
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 {
|
||||||
|
return { seed, x, y, z, w ->
|
||||||
|
billow(seed, x, y, z, 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,
|
||||||
|
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): Double {
|
||||||
|
var sum = 1.0 - Math.abs(noise(seed, x, y, z, w))
|
||||||
|
var amp = 1.0
|
||||||
|
|
||||||
|
var x = x
|
||||||
|
var y = y
|
||||||
|
var z = z
|
||||||
|
var w = w
|
||||||
|
for (i in 1 until octaves) {
|
||||||
|
x *= lacunarity
|
||||||
|
y *= lacunarity
|
||||||
|
z *= lacunarity
|
||||||
|
w *= lacunarity
|
||||||
|
amp *= gain
|
||||||
|
sum -= (1.0 - abs(noise(seed + i, x, y, z, w))) * amp
|
||||||
|
}
|
||||||
|
return sum
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun rigid(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 - Math.abs(noise(seed, x, y, z))
|
||||||
|
var amp = 1.0
|
||||||
|
|
||||||
|
var x = x
|
||||||
|
var y = y
|
||||||
|
var z = z
|
||||||
|
for (i in 1 until octaves) {
|
||||||
|
x *= lacunarity
|
||||||
|
y *= lacunarity
|
||||||
|
z *= lacunarity
|
||||||
|
amp *= gain
|
||||||
|
sum -= (1.0 - abs(noise(seed + i, x, y, z))) * amp
|
||||||
}
|
}
|
||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
@@ -85,21 +243,40 @@ inline fun rigid(seed: Int, x: Double, y: Double, crossinline noise: (Int, Doubl
|
|||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun rigid(seed: Int, x: Double, y: Double, z: Double, crossinline noise: (Int, Double, Double, Double) -> Double,
|
inline fun rigid(seed: Int, x: Double, crossinline noise: (Int, Double) -> Double,
|
||||||
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): Double {
|
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): Double {
|
||||||
var sum = 1.0 - Math.abs(noise(seed, x, y, z))
|
var sum = 1.0 - abs(noise(seed, x))
|
||||||
var amp = 1.0
|
var amp = 1.0
|
||||||
|
|
||||||
var x = x
|
var x = x
|
||||||
var y = y
|
|
||||||
var z = z
|
|
||||||
for (i in 1 until octaves) {
|
for (i in 1 until octaves) {
|
||||||
x *= lacunarity
|
x *= lacunarity
|
||||||
y *= lacunarity
|
|
||||||
z *= lacunarity
|
|
||||||
amp *= gain
|
amp *= gain
|
||||||
sum -= (1.0 - Math.abs(noise(seed + i, x, y, z))) * amp
|
sum -= (1.0 - abs(noise(seed + i, x))) * amp
|
||||||
}
|
}
|
||||||
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 {
|
||||||
|
return { seed, x ->
|
||||||
|
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 {
|
||||||
|
return { seed, x, y ->
|
||||||
|
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 {
|
||||||
|
return { seed, x, y, z ->
|
||||||
|
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 {
|
||||||
|
return { seed, x, y, z, w ->
|
||||||
|
rigid(seed, x, y, z, w, noise, octaves, lacunarity, gain)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
37
orx-noise/src/main/kotlin/GaussianRandom.kt
Normal file
37
orx-noise/src/main/kotlin/GaussianRandom.kt
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package org.openrndr.extra.noise
|
||||||
|
|
||||||
|
import org.openrndr.math.Vector2
|
||||||
|
import org.openrndr.math.Vector3
|
||||||
|
import org.openrndr.math.Vector4
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
fun gaussian(mean: Double = 0.0, deviation: Double = 1.0, random: Random = Random.Default): Double {
|
||||||
|
var v1: Double
|
||||||
|
var v2: Double
|
||||||
|
var s: Double
|
||||||
|
do {
|
||||||
|
v1 = 2 * random.nextDouble() - 1
|
||||||
|
v2 = 2 * random.nextDouble() - 1
|
||||||
|
s = v1 * v1 + v2 * v2
|
||||||
|
} while (s >= 1 || s == 0.0)
|
||||||
|
val multiplier = StrictMath.sqrt(-2 * StrictMath.log(s) / s)
|
||||||
|
|
||||||
|
return v1 * multiplier * deviation + mean
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Double.Companion.gaussian(mean: Double = 0.0, deviation: Double = 1.0, random: Random = Random.Default): Double {
|
||||||
|
return gaussian(mean, deviation, random)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Vector2.Companion.gaussian(mean: Vector2 = Vector2.ZERO, deviation: Vector2 = Vector2.ONE, random: Random = Random.Default): Vector2 {
|
||||||
|
return Vector2(gaussian(mean.x, deviation.x, random), gaussian(mean.y, deviation.y, random))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Vector3.Companion.gaussian(mean: Vector3 = Vector3.ZERO, deviation: Vector3 = Vector3.ONE, random: Random = Random.Default): Vector3 {
|
||||||
|
return Vector3(gaussian(mean.x, deviation.x, random), gaussian(mean.y, deviation.y, random), gaussian(mean.z, deviation.z, random))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Vector4.Companion.gaussian(mean: Vector4 = Vector4.ZERO, deviation: Vector4 = Vector4.ONE, random: Random = Random.Default): Vector4 {
|
||||||
|
return Vector4(gaussian(mean.x, deviation.x, random), gaussian(mean.y, deviation.y, random), gaussian(mean.z, deviation.z, random), gaussian(mean.w, deviation.w, random))
|
||||||
|
}
|
||||||
|
|
||||||
72
orx-noise/src/main/kotlin/Gradient.kt
Normal file
72
orx-noise/src/main/kotlin/Gradient.kt
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
package org.openrndr.extra.noise
|
||||||
|
|
||||||
|
import org.openrndr.math.Vector2
|
||||||
|
import org.openrndr.math.Vector3
|
||||||
|
import org.openrndr.math.Vector4
|
||||||
|
|
||||||
|
inline fun gradient(
|
||||||
|
crossinline noise: (seed: Int, x: Double) -> Double,
|
||||||
|
seed: Int,
|
||||||
|
x: Double,
|
||||||
|
epsilon: Double = 0.01
|
||||||
|
): Double {
|
||||||
|
val xn = noise(seed, x - epsilon)
|
||||||
|
val xp = noise(seed, x + epsilon)
|
||||||
|
return (xp - xn) / (2.0 * epsilon)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun gradient(
|
||||||
|
crossinline noise: (seed: Int, x: Double, y: Double) -> Double,
|
||||||
|
seed: Int,
|
||||||
|
x: Double,
|
||||||
|
y: Double,
|
||||||
|
epsilon: Double = 0.01
|
||||||
|
): Vector2 {
|
||||||
|
val xn = noise(seed, x - epsilon, y)
|
||||||
|
val xp = noise(seed, x + epsilon, y)
|
||||||
|
val yn = noise(seed, x, y - epsilon)
|
||||||
|
val yp = noise(seed, x, y + epsilon)
|
||||||
|
return Vector2((xp - xn) / (2.0 * epsilon), (yp - yn) / (2.0 * epsilon))
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun gradient(
|
||||||
|
crossinline noise: (seed: Int, x: Double, y: Double, z: Double) -> Double,
|
||||||
|
seed: Int,
|
||||||
|
x: Double,
|
||||||
|
y: Double,
|
||||||
|
z: Double,
|
||||||
|
epsilon: Double = 0.01
|
||||||
|
): Vector3 {
|
||||||
|
val xn = noise(seed, x - epsilon, y, z)
|
||||||
|
val xp = noise(seed, x + epsilon, y, z)
|
||||||
|
val yn = noise(seed, x, y - epsilon, z)
|
||||||
|
val yp = noise(seed, x, y + epsilon, z)
|
||||||
|
val zn = noise(seed, x, y, z - epsilon)
|
||||||
|
val zp = noise(seed, x, y, z + epsilon)
|
||||||
|
return Vector3((xp - xn) / (2.0 * epsilon), (yp - yn) / (2.0 * epsilon), (zp - zn) / (2.0 * epsilon))
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun gradient(
|
||||||
|
crossinline noise: (seed: Int, x: Double, y: Double, z: Double, w: Double) -> Double,
|
||||||
|
seed: Int,
|
||||||
|
x: Double,
|
||||||
|
y: Double,
|
||||||
|
z: Double,
|
||||||
|
w: Double,
|
||||||
|
epsilon: Double = 0.01
|
||||||
|
): Vector4 {
|
||||||
|
val xn = noise(seed, x - epsilon, y, z, w)
|
||||||
|
val xp = noise(seed, x + epsilon, y, z, w)
|
||||||
|
val yn = noise(seed, x, y - epsilon, z, w)
|
||||||
|
val yp = noise(seed, x, y + epsilon, z, w)
|
||||||
|
val zn = noise(seed, x, y, z - epsilon, w)
|
||||||
|
val zp = noise(seed, x, y, z + epsilon, w)
|
||||||
|
val wn = noise(seed, x, y, z, w - epsilon)
|
||||||
|
val wp = noise(seed, x, y, z, w + epsilon)
|
||||||
|
return Vector4(
|
||||||
|
(xp - xn) / (2.0 * epsilon),
|
||||||
|
(yp - yn) / (2.0 * epsilon),
|
||||||
|
(zp - zn) / (2.0 * epsilon),
|
||||||
|
(wp - wn) / (2.0 * epsilon)
|
||||||
|
)
|
||||||
|
}
|
||||||
9
orx-noise/src/main/kotlin/PerlinNoise1D.kt
Normal file
9
orx-noise/src/main/kotlin/PerlinNoise1D.kt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package org.openrndr.extra.noise
|
||||||
|
|
||||||
|
fun perlin(seed: Int, x: Double) = perlin(seed, x, ::linear)
|
||||||
|
fun perlinLinear(seed: Int, x: Double) = perlin(seed, x, ::linear)
|
||||||
|
fun perlinQuintic(seed: Int, x: Double) = perlin(seed, x, ::quintic)
|
||||||
|
fun perlinHermite(seed: Int, x: Double) = perlin(seed, x, ::hermite)
|
||||||
|
|
||||||
|
inline fun perlin(seed: Int, x: Double, crossinline interpolator: (Double) -> Double): Double =
|
||||||
|
perlin(seed, x, 0.0, interpolator)
|
||||||
3
orx-noise/src/main/kotlin/SimplexNoise1D.kt
Normal file
3
orx-noise/src/main/kotlin/SimplexNoise1D.kt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
package org.openrndr.extra.noise
|
||||||
|
|
||||||
|
fun simplex(seed: Int, x: Double): Double = simplex(seed, x, 0.0)
|
||||||
@@ -3,11 +3,7 @@ package org.openrndr.extra.noise
|
|||||||
private const val G2 = 1.0 / 4.0
|
private const val G2 = 1.0 / 4.0
|
||||||
private const val F2 = 1.0 / 2.0
|
private const val F2 = 1.0 / 2.0
|
||||||
|
|
||||||
fun simplexLinear(seed: Int, x: Double, y: Double) = simplex(seed, x, y, ::linear)
|
fun simplex(seed: Int, x: Double, y: Double): Double {
|
||||||
fun simplexQuintic(seed: Int, x: Double, y: Double) = simplex(seed, x, y, ::quintic)
|
|
||||||
fun simplexHermite(seed: Int, x: Double, y: Double) = simplex(seed, x, y, ::hermite)
|
|
||||||
|
|
||||||
fun simplex(seed: Int, x: Double, y: Double, interpolator: (Double) -> Double = ::linear): Double {
|
|
||||||
var t = (x + y) * F2
|
var t = (x + y) * F2
|
||||||
val i = (x + t).fastFloor()
|
val i = (x + t).fastFloor()
|
||||||
val j = (y + t).fastFloor()
|
val j = (y + t).fastFloor()
|
||||||
@@ -16,8 +12,8 @@ fun simplex(seed: Int, x: Double, y: Double, interpolator: (Double) -> Double =
|
|||||||
val X0 = i - t
|
val X0 = i - t
|
||||||
val Y0 = j - t
|
val Y0 = j - t
|
||||||
|
|
||||||
val x0 = interpolator(x - X0)
|
val x0 = x - X0
|
||||||
val y0 = interpolator(y - Y0)
|
val y0 = y - Y0
|
||||||
|
|
||||||
val i1: Int
|
val i1: Int
|
||||||
val j1: Int
|
val j1: Int
|
||||||
@@ -29,10 +25,10 @@ fun simplex(seed: Int, x: Double, y: Double, interpolator: (Double) -> Double =
|
|||||||
j1 = 1
|
j1 = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
val x1 = x0 - i1 + G2
|
val x1 = (x0 - i1 + G2)
|
||||||
val y1 = y0 - j1 + G2
|
val y1 = (y0 - j1 + G2)
|
||||||
val x2 = x0 - 1 + F2
|
val x2 = (x0 - 1 + F2)
|
||||||
val y2 = y0 - 1 + F2
|
val y2 = (y0 - 1 + F2)
|
||||||
|
|
||||||
val n0: Double
|
val n0: Double
|
||||||
val n1: Double
|
val n1: Double
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
package org.openrndr.extra.noise
|
package org.openrndr.extra.noise
|
||||||
|
|
||||||
fun simplexLinear(seed: Int, x: Double, y: Double, z: Double) = simplex(seed, x, y, z, ::linear)
|
|
||||||
fun simplexQuintic(seed: Int, x: Double, y: Double, z: Double) = simplex(seed, x, y, z, ::quintic)
|
|
||||||
fun simplexHermite(seed: Int, x: Double, y: Double, z: Double) = simplex(seed, x, y, z, ::hermite)
|
|
||||||
|
|
||||||
fun simplex(seed: Int, x: Double, y: Double, z: Double, interpolator: (Double) -> Double = ::linear): Double {
|
fun simplex(seed: Int, x: Double, y: Double, z: Double): Double {
|
||||||
|
|
||||||
val t = (x + y + z) / 3.0
|
val t = (x + y + z) / 3.0
|
||||||
val i = (x + t).fastFloor()
|
val i = (x + t).fastFloor()
|
||||||
@@ -12,9 +9,9 @@ fun simplex(seed: Int, x: Double, y: Double, z: Double, interpolator: (Double) -
|
|||||||
val k = (z + t).fastFloor()
|
val k = (z + t).fastFloor()
|
||||||
|
|
||||||
val t2 = (i + j + k) / 6.0
|
val t2 = (i + j + k) / 6.0
|
||||||
val x0 = interpolator(x - (i - t2))
|
val x0 = x - (i - t2)
|
||||||
val y0 = interpolator(y - (j - t2))
|
val y0 = y - (j - t2)
|
||||||
val z0 = interpolator(z - (k - t2))
|
val z0 = z - (k - t2)
|
||||||
|
|
||||||
val i1: Int
|
val i1: Int
|
||||||
val j1: Int
|
val j1: Int
|
||||||
|
|||||||
@@ -14,11 +14,8 @@ private val SIMPLEX_4D = byteArrayOf(
|
|||||||
private const val F4 = ((2.23606797 - 1.0) / 4.0)
|
private const val F4 = ((2.23606797 - 1.0) / 4.0)
|
||||||
private const val G4 = ((5.0 - 2.23606797) / 20.0)
|
private const val G4 = ((5.0 - 2.23606797) / 20.0)
|
||||||
|
|
||||||
fun simplexLinear(seed: Int, x: Double, y: Double, z: Double, w: Double) = simplex(seed, x, y, z, w, ::linear)
|
|
||||||
fun simplexQuintic(seed: Int, x: Double, y: Double, z: Double, w: Double) = simplex(seed, x, y, z, w, ::quintic)
|
|
||||||
fun simplexHermite(seed: Int, x: Double, y: Double, z: Double, w: Double) = simplex(seed, x, y, z, w, ::hermite)
|
|
||||||
|
|
||||||
fun simplex(seed: Int, x: Double, y: Double, z: Double, w: Double, interpolator: (Double) -> Double = ::linear): Double {
|
fun simplex(seed: Int, x: Double, y: Double, z: Double, w: Double): Double {
|
||||||
|
|
||||||
var t = (x + y + z + w) * F4
|
var t = (x + y + z + w) * F4
|
||||||
val i = (x + t).fastFloor()
|
val i = (x + t).fastFloor()
|
||||||
@@ -27,10 +24,10 @@ fun simplex(seed: Int, x: Double, y: Double, z: Double, w: Double, interpolator:
|
|||||||
val l = (w + t).fastFloor()
|
val l = (w + t).fastFloor()
|
||||||
|
|
||||||
val t2 = (i + j + k + l) * G4
|
val t2 = (i + j + k + l) * G4
|
||||||
val x0 = interpolator(x - (i - t2))
|
val x0 = x - (i - t2)
|
||||||
val y0 = interpolator(y - (j - t2))
|
val y0 = y - (j - t2)
|
||||||
val z0 = interpolator(z - (k - t2))
|
val z0 = z - (k - t2)
|
||||||
val w0 = interpolator(w - (l - t2))
|
val w0 = w - (l - t2)
|
||||||
|
|
||||||
var c = if (x0 > y0) 32 else 0
|
var c = if (x0 > y0) 32 else 0
|
||||||
c += if (x0 > z0) 16 else 0
|
c += if (x0 > z0) 16 else 0
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ fun random(min: Double = -1.0, max: Double = 1.0, random: Random = Random.Defaul
|
|||||||
return (random.nextDouble() * (max - min)) + min
|
return (random.nextDouble() * (max - min)) + min
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fun Double.Companion.uniform(min: Double = -1.0, max: Double = 1.0, random: Random = Random.Default): Double {
|
fun Double.Companion.uniform(min: Double = -1.0, max: Double = 1.0, random: Random = Random.Default): Double {
|
||||||
return (random.nextDouble() * (max - min)) + min
|
return (random.nextDouble() * (max - min)) + min
|
||||||
}
|
}
|
||||||
|
|||||||
8
orx-noise/src/main/kotlin/ValueNoise1D.kt
Normal file
8
orx-noise/src/main/kotlin/ValueNoise1D.kt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
package org.openrndr.extra.noise
|
||||||
|
|
||||||
|
fun valueLinear(seed: Int, x: Double) = value(seed, x, ::linear)
|
||||||
|
fun valueQuintic(seed: Int, x: Double) = value(seed, x, ::quintic)
|
||||||
|
fun valueHermite(seed: Int, x: Double) = value(seed, x, ::hermite)
|
||||||
|
|
||||||
|
inline fun value(seed: Int, x: Double, crossinline interpolation: (Double) -> Double = ::linear): Double =
|
||||||
|
value(seed, x, 0.0)
|
||||||
33
orx-noise/src/test/kotlin/TestGradient.kt
Normal file
33
orx-noise/src/test/kotlin/TestGradient.kt
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import org.openrndr.extra.noise.*
|
||||||
|
import org.spekframework.spek2.Spek
|
||||||
|
import org.spekframework.spek2.style.specification.describe
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
object TestGradient : Spek({
|
||||||
|
describe("Noise") {
|
||||||
|
it("has a gradient") {
|
||||||
|
gradient(::perlinLinear, 100, 0.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("FBM noise func") {
|
||||||
|
it("has a gradient") {
|
||||||
|
val func = fbmFunc1D(::perlinLinear)
|
||||||
|
gradient(func, 100, 0.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("Billow noise func") {
|
||||||
|
it("has a gradient") {
|
||||||
|
val func = billowFunc1D(::perlinLinear)
|
||||||
|
gradient(func, 100, 0.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("Rigid noise func") {
|
||||||
|
it("has a gradient") {
|
||||||
|
val func = rigidFunc1D(::perlinLinear)
|
||||||
|
gradient(func, 100, 0.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user