Created
May 23, 2022 12:53
-
-
Save PolyRocketMatt/e999db49066b5cbe4145427b870eb7dd to your computer and use it in GitHub Desktop.
Polynomial-Noise Kotlin port (from https://www.researchgate.net/profile/Yann-Thorimbert/publication/309037528_Polynomial_method_for_Procedural_Terrain_Generation/links/5c0659e492851c6ca1fc69fd/Polynomial-method-for-Procedural-Terrain-Generation.pdf)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Copyright (c) <2022> <Yann Thorimbert, Bastien Chopard, Matthias Kovacic> | |
* Permission is hereby granted, free of charge, to any person | |
* obtaining a copy of this software and associated documentation | |
* files (the "Software"), to deal in the Software without | |
* restriction, including without limitation the rights to use, | |
* copy, modify, merge, publish, distribute, sublicense, and/or sell | |
* copies of the Software, and to permit persons to whom the | |
* Software is furnished to do so, subject to the following | |
* conditions: | |
* | |
* The above copyright notice and this permission notice shall be | |
* included in all copies or substantial portions of the Software. | |
* | |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | |
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
* OTHER DEALINGS IN THE SOFTWARE. | |
*/ | |
import kotlin.random.Random | |
class PolynomialNoise( | |
private val seed: Int, | |
private val octaves: Int, | |
private val resolution: Int | |
) { | |
fun noise(): Array<FloatArray> { | |
val rng = Random(seed) | |
// Build random array | |
val boundary = Array(resolution) { FloatArray(resolution) { rng.nextFloat() } } | |
val result = Array(resolution) { FloatArray(resolution) { 0.0f } } | |
var deltaX = 0.0f | |
var deltaY = 0.0f | |
var a = 0.0f | |
var h00 = 0.0f | |
var h01: Float | |
var h10: Float | |
var h11: Float | |
var changeCell = true | |
var amplitude = 1.0f | |
var res = this.resolution | |
for (i in 0 until octaves) { | |
val delta = 1.0f / res | |
var idx = 0 | |
var idx1 = 0 | |
var xRel = 0f | |
for (x in 0 until this.resolution) { | |
var idy = 0 | |
var idy1 = 0 | |
var yRel = 0f | |
val smoothX = this.smoothStep(xRel) | |
if (x % res == 0) { | |
idx = idx1 | |
idx1 += res - 1 | |
changeCell = true | |
} | |
for (y in 0 until this.resolution) { | |
val smoothY = this.smoothStep(yRel) | |
if (y % res == 0) { | |
idy = idy1 | |
idy1 += res - 1 | |
changeCell = true | |
} | |
if (changeCell) { | |
h00 = boundary[idx][idy] | |
h01 = boundary[idx][idy1] | |
h10 = boundary[idx1][idy] | |
h11 = boundary[idx1][idy1] | |
deltaX = h10 - h00 | |
deltaY = h01 - h00 | |
a = deltaX - h11 + h01 | |
changeCell = false | |
} | |
// | |
val dh = h00 + smoothX * deltaX + smoothY * deltaY + | |
a * (xRel * yRel - smoothX * yRel - smoothY * xRel) | |
result[x][y] += amplitude * dh | |
yRel += delta | |
if (yRel >= 1f) yRel = 0f | |
} | |
xRel += delta | |
if (xRel >= 1f) xRel = 0f | |
} | |
res /= 2 | |
amplitude /= 2f | |
} | |
return result | |
} | |
fun smoothStep(x: Float): Float = 3.0f * x * x - 2.0f * x * x * x | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment