Add 1d noise versions, Gaussian noise, noise gradients, 4D fractal functions

This commit is contained in:
Edwin Jakobs
2020-03-12 12:40:12 +01:00
parent 5b0775289c
commit eff96bac94
13 changed files with 538 additions and 164 deletions

View File

@@ -32,57 +32,69 @@ These are a mostly straight port from FastNoise-Java but have a slightly differe
### Perlin noise
```
// -- 1d
val v0 = perlinLinear(seed, x)
val v1 = perlinQuintic(seed, x)
val v2 = perlinHermite(seed, x)
// -- 2d
val v0 = perlinLinear(seed, x, y)
val v1 = perlinQuintic(seed, x, y)
val v2 = perlinHermite(seed, x, y)
val v3 = perlinLinear(seed, x, y)
val v4 = perlinQuintic(seed, x, y)
val v5 = 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)
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 v0 = valueLinear(seed, x, y)
val v1 = valueQuintic(seed, x, y)
val v2 = valueHermite(seed, x, y)
val v2 = valueLinear(seed, x, y)
val v3 = valueQuintic(seed, x, y)
val v4 = 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)
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 v0 = simplexLinear(seed, x, y)
val v1 = simplexQuintic(seed, x, y)
val v2 = simplexHermite(seed, x, y)
val v1 = simplex(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)
val v2 = simplex(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)
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 = cubicLinear(seed, x, y)
val v0 = cubic(seed, x, y)
val v1 = cubicQuintic(seed, x, y)
val v2 = cubicHermite(seed, x, y)
// -- 3d
val v3 = cubicLinear(seed, x, y, z)
val v3 = cubic(seed, x, y, z)
val v4 = cubicQuintic(seed, x, y, z)
val v5 = cubicHermite(seed, x, y ,z)
```
@@ -94,22 +106,36 @@ 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)
// 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)
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)
// 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
```
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)
// 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)
@@ -118,11 +144,18 @@ 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)
// 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)
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)
// 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)
```

View 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)
}

View File

@@ -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)
}
}

View 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))
}

View 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)
)
}

View 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)

View File

@@ -0,0 +1,3 @@
package org.openrndr.extra.noise
fun simplex(seed: Int, x: Double): Double = simplex(seed, x, 0.0)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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
}

View 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)

View 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)
}
}
})