Add 1d noise versions, Gaussian noise, noise gradients, 4D fractal functions
This commit is contained in:
@@ -1,128 +1,161 @@
|
||||
# orx-noise
|
||||
|
||||
A collection of noisy functions
|
||||
|
||||
## Uniform random numbers
|
||||
|
||||
```kotlin
|
||||
val sua = Double.uniform()
|
||||
val sub = Double.uniform(-1.0, 1.0)
|
||||
|
||||
val v2ua = Vector2.uniform()
|
||||
val v2ub = Vector2.uniform(-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 v3ua = Vector3.uniform()
|
||||
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 v3ur = Vector3.uniformRing(0.5, 1.0)
|
||||
|
||||
val v4ua = Vector4.uniform()
|
||||
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 v4ur = Vector4.uniformRing(0.5, 1.0)
|
||||
|
||||
val ringSamples = List(500) { Vector2.uniformRing() }
|
||||
```
|
||||
|
||||
## Multi-dimensional noise
|
||||
|
||||
These are a mostly straight port from FastNoise-Java but have a slightly different interface.
|
||||
|
||||
### Perlin noise
|
||||
```
|
||||
// -- 2d
|
||||
val v0 = perlinLinear(seed, x, y)
|
||||
val v1 = perlinQuintic(seed, x, y)
|
||||
val v2 = perlinHermite(seed, x, y)
|
||||
|
||||
// -- 3d
|
||||
val v3 = perlinLinear(seed, x, y, z)
|
||||
val v4 = perlinQuintic(seed, x, y, z)
|
||||
val v5 = perlinHermite(seed, x, y, z)
|
||||
```
|
||||
|
||||
### Value noise
|
||||
```
|
||||
// -- 2d
|
||||
val v0 = valueLinear(seed, x, y)
|
||||
val v1 = valueQuintic(seed, x, y)
|
||||
val v2 = valueHermite(seed, x, y)
|
||||
|
||||
// -- 3d
|
||||
val v3 = valueLinear(seed, x, y, z)
|
||||
val v4 = valueQuintic(seed, x, y, z)
|
||||
val v5 = valueHermite(seed, x, y ,z)
|
||||
```
|
||||
|
||||
### Simplex noise
|
||||
```
|
||||
// -- 2d
|
||||
val v0 = simplexLinear(seed, x, y)
|
||||
val v1 = simplexQuintic(seed, x, y)
|
||||
val v2 = simplexHermite(seed, x, y)
|
||||
|
||||
// -- 3d
|
||||
val v3 = simplexLinear(seed, x, y, z)
|
||||
val v4 = simplexQuintic(seed, x, y, z)
|
||||
val v5 = simplexHermite(seed, x, y ,z)
|
||||
|
||||
// -- 4d
|
||||
val v6 = simplexLinear(seed, x, y, z, w)
|
||||
val v7 = simplexQuintic(seed, x, y, z, w)
|
||||
val v8 = simplexHermite(seed, x, y, z, w)
|
||||
```
|
||||
|
||||
### Cubic noise
|
||||
```
|
||||
// -- 2d
|
||||
val v0 = cubicLinear(seed, x, y)
|
||||
val v1 = cubicQuintic(seed, x, y)
|
||||
val v2 = cubicHermite(seed, x, y)
|
||||
|
||||
// -- 3d
|
||||
val v3 = cubicLinear(seed, x, y, z)
|
||||
val v4 = cubicQuintic(seed, x, y, z)
|
||||
val v5 = cubicHermite(seed, x, y ,z)
|
||||
```
|
||||
|
||||
### Fractal noise
|
||||
|
||||
The library provides 3 functions with which fractal noise can be composed.
|
||||
|
||||
#### Fractal brownian motion (FBM)
|
||||
|
||||
```
|
||||
val v0 = fbm(seed, x, y, ::perlinLinear, octaves, lacunarity, gain)
|
||||
val v1 = fbm(seed, x, y, ::simplexLinear, octaves, lacunarity, gain)
|
||||
val v2 = fbm(seed, x, y, ::valueLinear, octaves, lacunarity, gain)
|
||||
|
||||
val v3 = fbm(seed, x, y, z, ::perlinLinear, octaves, lacunarity, gain)
|
||||
val v4 = fbm(seed, x, y, z, ::simplexLinear, octaves, lacunarity, gain)
|
||||
val v5 = fbm(seed, x, y, z, ::valueLinear, octaves, lacunarity, gain)
|
||||
```
|
||||
|
||||
#### Rigid
|
||||
|
||||
```
|
||||
val v0 = rigid(seed, x, y, ::perlinLinear, octaves, lacunarity, gain)
|
||||
val v1 = rigid(seed, x, y, ::simplexLinear, octaves, lacunarity, gain)
|
||||
val v2 = rigid(seed, x, y, ::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)
|
||||
val v5 = rigid(seed, x, y, z, ::valueLinear, octaves, lacunarity, gain)
|
||||
```
|
||||
|
||||
#### Billow
|
||||
|
||||
```
|
||||
val v0 = billow(seed, x, y, ::perlinLinear, octaves, lacunarity, gain)
|
||||
val v1 = billow(seed, x, y, ::perlinLinear, octaves, lacunarity, gain)
|
||||
val v2 = billow(seed, x, y, ::perlinLinear, octaves, lacunarity, gain)
|
||||
|
||||
val v3 = billow(seed, x, y, z, ::perlinLinear, octaves, lacunarity, gain)
|
||||
val v4 = billow(seed, x, y, z, ::perlinLinear, octaves, lacunarity, gain)
|
||||
val v5 = billow(seed, x, y, z, ::perlinLinear, octaves, lacunarity, gain)
|
||||
```
|
||||
# orx-noise
|
||||
|
||||
A collection of noisy functions
|
||||
|
||||
## Uniform random numbers
|
||||
|
||||
```kotlin
|
||||
val sua = Double.uniform()
|
||||
val sub = Double.uniform(-1.0, 1.0)
|
||||
|
||||
val v2ua = Vector2.uniform()
|
||||
val v2ub = Vector2.uniform(-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 v3ua = Vector3.uniform()
|
||||
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 v3ur = Vector3.uniformRing(0.5, 1.0)
|
||||
|
||||
val v4ua = Vector4.uniform()
|
||||
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 v4ur = Vector4.uniformRing(0.5, 1.0)
|
||||
|
||||
val ringSamples = List(500) { Vector2.uniformRing() }
|
||||
```
|
||||
|
||||
## Multi-dimensional noise
|
||||
|
||||
These are a mostly straight port from FastNoise-Java but have a slightly different interface.
|
||||
|
||||
### Perlin noise
|
||||
```
|
||||
// -- 1d
|
||||
val v0 = perlinLinear(seed, x)
|
||||
val v1 = perlinQuintic(seed, x)
|
||||
val v2 = perlinHermite(seed, x)
|
||||
|
||||
// -- 2d
|
||||
val v3 = perlinLinear(seed, x, y)
|
||||
val v4 = perlinQuintic(seed, x, y)
|
||||
val v5 = perlinHermite(seed, x, y)
|
||||
|
||||
// -- 3d
|
||||
val v6 = perlinLinear(seed, x, y, z)
|
||||
val v7 = perlinQuintic(seed, x, y, z)
|
||||
val v8 = perlinHermite(seed, x, y, z)
|
||||
```
|
||||
|
||||
### Value noise
|
||||
```
|
||||
// -- 1d
|
||||
val v0 = valueLinear(seed, x)
|
||||
val v1 = valueQuintic(seed, x)
|
||||
val v2 = valueHermite(seed, x)
|
||||
|
||||
// -- 2d
|
||||
val v2 = valueLinear(seed, x, y)
|
||||
val v3 = valueQuintic(seed, x, y)
|
||||
val v4 = valueHermite(seed, x, y)
|
||||
|
||||
// -- 3d
|
||||
val v5 = valueLinear(seed, x, y, z)
|
||||
val v6 = valueQuintic(seed, x, y, z)
|
||||
val v7 = valueHermite(seed, x, y ,z)
|
||||
```
|
||||
|
||||
### Simplex noise
|
||||
```
|
||||
// -- 1d
|
||||
val v0 = simplex(seed, x)
|
||||
|
||||
// -- 2d
|
||||
val v1 = simplex(seed, x, y)
|
||||
|
||||
// -- 3d
|
||||
val v2 = simplex(seed, x, y, z)
|
||||
|
||||
// -- 4d
|
||||
val v3 = simplex(seed, x, y, z, w)
|
||||
```
|
||||
|
||||
### Cubic noise
|
||||
```
|
||||
// -- 1d
|
||||
val v0 = cubic(seed, x, y)
|
||||
val v1 = cubicQuintic(seed, x, y)
|
||||
val v2 = cubicHermite(seed, x, y)
|
||||
|
||||
// -- 2d
|
||||
val v0 = cubic(seed, x, y)
|
||||
val v1 = cubicQuintic(seed, x, y)
|
||||
val v2 = cubicHermite(seed, x, y)
|
||||
|
||||
// -- 3d
|
||||
val v3 = cubic(seed, x, y, z)
|
||||
val v4 = cubicQuintic(seed, x, y, z)
|
||||
val v5 = cubicHermite(seed, x, y ,z)
|
||||
```
|
||||
|
||||
### Fractal noise
|
||||
|
||||
The library provides 3 functions with which fractal noise can be composed.
|
||||
|
||||
#### Fractal brownian motion (FBM)
|
||||
|
||||
```
|
||||
// 1d
|
||||
val v0 = fbm(seed, x, ::perlinLinear, octaves, lacunarity, gain)
|
||||
val v1 = fbm(seed, x, ::simplexLinear, octaves, lacunarity, gain)
|
||||
val v2 = fbm(seed, x, ::valueLinear, octaves, lacunarity, gain)
|
||||
|
||||
// 2d
|
||||
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)
|
||||
|
||||
// 3d
|
||||
val v6 = fbm(seed, x, y, z, ::perlinLinear, octaves, lacunarity, gain)
|
||||
val v7 = fbm(seed, x, y, z, ::simplexLinear, octaves, lacunarity, gain)
|
||||
val v8 = fbm(seed, x, y, z, ::valueLinear, octaves, lacunarity, gain)
|
||||
```
|
||||
|
||||
#### Rigid
|
||||
|
||||
```
|
||||
// 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
|
||||
|
||||
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,
|
||||
octaves: Int = 8, lacunarity: Double = 0.5, gain: Double = 0.5): Double {
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
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 {
|
||||
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
|
||||
}
|
||||
|
||||
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,
|
||||
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)
|
||||
@@ -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,
|
||||
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 x = x
|
||||
@@ -64,7 +146,83 @@ inline fun billow(seed: Int, x: Double, y: Double, crossinline noise: (Int, Doub
|
||||
x *= lacunarity
|
||||
y *= lacunarity
|
||||
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
|
||||
}
|
||||
@@ -85,21 +243,40 @@ inline fun rigid(seed: Int, x: Double, y: Double, crossinline noise: (Int, Doubl
|
||||
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 {
|
||||
var sum = 1.0 - Math.abs(noise(seed, x, y, z))
|
||||
var sum = 1.0 - abs(noise(seed, x))
|
||||
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 - Math.abs(noise(seed + i, x, y, z))) * amp
|
||||
sum -= (1.0 - abs(noise(seed + i, x))) * amp
|
||||
}
|
||||
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 F2 = 1.0 / 2.0
|
||||
|
||||
fun simplexLinear(seed: Int, x: Double, y: Double) = simplex(seed, x, y, ::linear)
|
||||
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 {
|
||||
fun simplex(seed: Int, x: Double, y: Double): Double {
|
||||
var t = (x + y) * F2
|
||||
val i = (x + 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 Y0 = j - t
|
||||
|
||||
val x0 = interpolator(x - X0)
|
||||
val y0 = interpolator(y - Y0)
|
||||
val x0 = x - X0
|
||||
val y0 = y - Y0
|
||||
|
||||
val i1: Int
|
||||
val j1: Int
|
||||
@@ -29,10 +25,10 @@ fun simplex(seed: Int, x: Double, y: Double, interpolator: (Double) -> Double =
|
||||
j1 = 1
|
||||
}
|
||||
|
||||
val x1 = x0 - i1 + G2
|
||||
val y1 = y0 - j1 + G2
|
||||
val x2 = x0 - 1 + F2
|
||||
val y2 = y0 - 1 + F2
|
||||
val x1 = (x0 - i1 + G2)
|
||||
val y1 = (y0 - j1 + G2)
|
||||
val x2 = (x0 - 1 + F2)
|
||||
val y2 = (y0 - 1 + F2)
|
||||
|
||||
val n0: Double
|
||||
val n1: Double
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
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 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 t2 = (i + j + k) / 6.0
|
||||
val x0 = interpolator(x - (i - t2))
|
||||
val y0 = interpolator(y - (j - t2))
|
||||
val z0 = interpolator(z - (k - t2))
|
||||
val x0 = x - (i - t2)
|
||||
val y0 = y - (j - t2)
|
||||
val z0 = z - (k - t2)
|
||||
|
||||
val i1: 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 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
|
||||
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 t2 = (i + j + k + l) * G4
|
||||
val x0 = interpolator(x - (i - t2))
|
||||
val y0 = interpolator(y - (j - t2))
|
||||
val z0 = interpolator(z - (k - t2))
|
||||
val w0 = interpolator(w - (l - t2))
|
||||
val x0 = x - (i - t2)
|
||||
val y0 = y - (j - t2)
|
||||
val z0 = z - (k - t2)
|
||||
val w0 = w - (l - t2)
|
||||
|
||||
var c = if (x0 > y0) 32 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
|
||||
}
|
||||
|
||||
|
||||
|
||||
fun Double.Companion.uniform(min: Double = -1.0, max: Double = 1.0, random: Random = Random.Default): Double {
|
||||
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