[orx-noise] Add demos and extensions for uniform simplex sampling

This commit is contained in:
Edwin Jakobs
2025-02-26 22:08:11 +01:00
parent 6ad584a262
commit 90d9e4685e
5 changed files with 336 additions and 1 deletions

View File

@@ -0,0 +1,59 @@
package simplexrange
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.extra.math.simplexrange.SimplexRange3D
import kotlin.random.Random
import org.openrndr.extra.noise.simplexrange.uniform
import org.openrndr.extra.noise.simplexrange.uniformCube
/**
* This demo creates a dynamic graphical output utilizing simplex and
* linear interpolation-based color ranges.
*
* Functionalities:
* - Defines a list of base colors converted to LAB color space for smooth interpolation.
* - Constructs a 3D simplex range and a 2D linear range for color sampling.
* - Randomly populates two sections of the screen with rectangles filled with colors
* sampled from simplex and linear ranges respectively.
* - Draws a vertical divider line in the middle of the application window.
*/
fun main() {
application {
configure {
width = 720
height = 720
}
program {
extend {
val colors = listOf(ColorRGBa.BLACK, ColorRGBa.RED, ColorRGBa.GREEN, ColorRGBa.BLUE).map { it.toLABa() }
drawer.stroke = null
val sr = SimplexRange3D(colors[0], colors[1], colors[2], colors[3])
val r = Random((seconds * 2).toInt())
// Draw the simplex sampling on the left
drawer.rectangles {
for (y in 0 until 40) {
for (x in 0 until 20) {
fill = sr.uniform(r).toRGBa()
rectangle(x * width / 40.0, y * height / 40.0, width / 40.0, height / 40.0)
}
}
}
// Draw the bilinear sampling on the right
drawer.rectangles {
for (y in 0 until 40) {
for (x in 20 until 40) {
fill = sr.uniformCube(r).toRGBa()
rectangle(x * width / 40.0, y * height / 40.0, width / 40.0, height / 40.0)
}
}
}
drawer.stroke = ColorRGBa.BLACK
drawer.lineSegment(drawer.bounds.vertical(0.5))
}
}
}
}

View File

@@ -0,0 +1,91 @@
package simplexrange
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.draw.isolated
import kotlin.random.Random
import org.openrndr.extra.noise.simplexrange.uniformSimplex
import org.openrndr.math.Polar
import org.openrndr.math.Vector2
import kotlin.math.cos
import kotlin.math.floor
/**
* This demo creates a dynamic graphical output utilizing simplex and
* linear interpolation-based color ranges.
*
* Functionalities:
* - Defines a list of base colors converted to LAB color space for smooth interpolation.
* - Constructs a 3D simplex range and a 2D linear range for color sampling.
* - Randomly populates two sections of the screen with rectangles filled with colors
* sampled from simplex and linear ranges respectively.
* - Draws a vertical divider line in the middle of the application window.
*/
fun main() {
application {
configure {
width = 720
height = 720
}
program {
extend {
val positions = (0 until 3).map { Polar((30.0 + it * 120.0), 180.0).cartesian }
val colors = listOf(ColorRGBa.PINK, ColorRGBa.RED, ColorRGBa.BLUE).map { it.toLABa() }
val freq = 1.0
drawer.stroke = null
val power = cos(floor(seconds*freq)/freq) *16.0 + 16.0
drawer.isolated {
drawer.translate(drawer.bounds.position(0.25,0.25) + Vector2(0.0, 40.0))
val rp = Random((seconds * freq).toInt())
val rc = Random((seconds * freq).toInt())
for (i in 0 until 32 * 32) {
drawer.fill = colors.uniformSimplex(rc, 1, power).toRGBa()
drawer.circle(positions.uniformSimplex(rp, 1, power), 2.0)
}
}
drawer.isolated {
drawer.translate(drawer.bounds.position(0.75,0.75) + Vector2(0.0, 40.0))
val rp = Random((seconds * freq).toInt())
val rc = Random((seconds * freq).toInt())
for (i in 0 until 32 * 32) {
drawer.fill = colors.uniformSimplex(rc, 2, power).toRGBa()
drawer.circle(positions.uniformSimplex(rp, 2, power), 2.0)
}
}
drawer.isolated {
drawer.stroke = null
val rc = Random((seconds * freq).toInt())
drawer.translate(drawer.bounds.position(0.5,0.0) + Vector2(20.0, 20.0))
for (i in 0 until 32 * 32) {
val x = i.mod(32)
val y = i / 32
drawer.fill = colors.uniformSimplex(rc, 1, power).toRGBa()
drawer.rectangle(x * 10.0, y * 10.0, 10.0, 10.0)
}
}
drawer.isolated {
drawer.stroke = null
val rc = Random((seconds * freq).toInt())
drawer.translate(drawer.bounds.position(0.0,0.5) + Vector2(20.0, 20.0))
for (i in 0 until 32 * 32) {
val x = i.mod(32)
val y = i / 32
drawer.fill = colors.uniformSimplex(rc, 2, power).toRGBa()
drawer.rectangle(x * 10.0, y * 10.0, 10.0, 10.0)
}
}
}
}
}
}

View File

@@ -0,0 +1,64 @@
package simplexrange
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.draw.isolated
import org.openrndr.extra.math.simplexrange.SimplexRange2D
import org.openrndr.extra.math.simplexrange.SimplexRange3D
import org.openrndr.extra.noise.scatter
import kotlin.random.Random
import org.openrndr.extra.noise.simplexrange.uniformSimplex
import org.openrndr.math.Polar
import org.openrndr.math.Vector2
import org.openrndr.shape.Rectangle
import kotlin.math.cos
import kotlin.math.floor
/**
* This demo creates a dynamic graphical output utilizing simplex and
* linear interpolation-based color ranges.
*
* Functionalities:
* - Defines a list of base colors converted to LAB color space for smooth interpolation.
* - Constructs a 3D simplex range and a 2D linear range for color sampling.
* - Randomly populates two sections of the screen with rectangles filled with colors
* sampled from simplex and linear ranges respectively.
* - Draws a vertical divider line in the middle of the application window.
*/
fun main() {
application {
configure {
width = 720
height = 720
}
program {
extend {
val positions = (0 until 3).map { Polar((30.0 + it * 120.0), 180.0).cartesian }
val colors = listOf(ColorRGBa.PINK, ColorRGBa.RED, ColorRGBa.BLUE).map { it.toLABa() }
val positionsr = SimplexRange2D(positions[0], positions[1], positions[2])
val colorsr = SimplexRange2D(colors[0], colors[1], colors[2])
val freq = 1.0
drawer.stroke = null
val r = Random((seconds * freq).toInt())
val points = Rectangle(0.0, 0.0, 360.0, 360.0).scatter(10.0, random = r)
drawer.circles(points, 2.0)
val power = cos(floor(seconds*freq)/freq) *16.0 + 16.0
drawer.isolated {
drawer.translate(drawer.bounds.position(0.75,0.25) + Vector2(0.0, 40.0))
for (point in points) {
drawer.fill = colorsr.value(point.x/360.0, point.y/360.0).toRGBa()
drawer.circle(positionsr.value(point.x/360.0, point.y/360.0), 2.0)
}
}
}
}
}
}