[orx-math] Add orx-math module
This commit is contained in:
3
orx-math/README.md
Normal file
3
orx-math/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# orx-math
|
||||
|
||||
Mathematical utilities
|
||||
46
orx-math/build.gradle.kts
Normal file
46
orx-math/build.gradle.kts
Normal file
@@ -0,0 +1,46 @@
|
||||
@Suppress("DSL_SCOPE_VIOLATION")
|
||||
plugins {
|
||||
org.openrndr.extra.convention.`kotlin-multiplatform`
|
||||
// kotlinx-serialization ends up on the classpath through openrndr-math and Gradle doesn't know which
|
||||
// version was used. If openrndr were an included build, we probably wouldn't need to do this.
|
||||
// https://github.com/gradle/gradle/issues/20084
|
||||
id(libs.plugins.kotlin.serialization.get().pluginId)
|
||||
alias(libs.plugins.kotest.multiplatform)
|
||||
}
|
||||
|
||||
kotlin {
|
||||
sourceSets {
|
||||
val commonMain by getting {
|
||||
dependencies {
|
||||
implementation(libs.kotlin.serialization.core)
|
||||
implementation(libs.openrndr.math)
|
||||
}
|
||||
}
|
||||
|
||||
val commonTest by getting {
|
||||
dependencies {
|
||||
implementation(libs.kotlin.serialization.json)
|
||||
implementation(libs.kotest.assertions)
|
||||
implementation(libs.kotest.framework.engine)
|
||||
}
|
||||
}
|
||||
|
||||
val jvmTest by getting {
|
||||
dependencies {
|
||||
implementation(libs.kotlin.serialization.json)
|
||||
implementation(libs.kotest.assertions)
|
||||
implementation(libs.kotest.framework.engine)
|
||||
}
|
||||
}
|
||||
|
||||
val jvmDemo by getting {
|
||||
dependencies {
|
||||
implementation(project(":orx-camera"))
|
||||
implementation(project(":orx-mesh-generators"))
|
||||
implementation(project(":orx-color"))
|
||||
implementation(project(":orx-jvm:orx-gui"))
|
||||
implementation(project(":orx-shade-styles"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3
orx-math/src/commonMain/kotlin/Math.kt
Normal file
3
orx-math/src/commonMain/kotlin/Math.kt
Normal file
@@ -0,0 +1,3 @@
|
||||
package org.openrndr.extra.math
|
||||
|
||||
private fun placeholder() {}
|
||||
175
orx-math/src/commonMain/kotlin/linearrange/LinearRange.kt
Normal file
175
orx-math/src/commonMain/kotlin/linearrange/LinearRange.kt
Normal file
@@ -0,0 +1,175 @@
|
||||
package org.openrndr.extra.math.linearrange
|
||||
|
||||
import org.openrndr.math.*
|
||||
import kotlin.jvm.JvmRecord
|
||||
|
||||
/**
|
||||
* Represents a linear range between two values, defined by a start and an end point,
|
||||
* where the type of the values implements the `LinearType` interface.
|
||||
* This class allows interpolation and evenly spaced steps within the range.
|
||||
*
|
||||
* @param T The type of the range's start and end values, constrained by the `LinearType` interface.
|
||||
* @property start The starting value of the range.
|
||||
* @property end The ending value of the range.
|
||||
*/
|
||||
@JvmRecord
|
||||
data class LinearRange1D<T : LinearType<T>>(val start: T, val end: T) :
|
||||
LinearType<LinearRange1D<T>>,
|
||||
Parametric1D<T> {
|
||||
/**
|
||||
* Computes a value interpolated linearly between the start and end points of the range based on the parameter `t`.
|
||||
*
|
||||
* @param t A parameter in the range [0.0, 1.0]. When `t` is 0.0, the result is the start value.
|
||||
* When `t` is 1.0, the result is the end value. Intermediate values of `t` result in a linear interpolation.
|
||||
* @return The interpolated value between the start and end points of the range.
|
||||
*/
|
||||
override fun value(t: Double) = start * (1.0 - t) + end * t
|
||||
|
||||
fun steps(count: Int): Sequence<T> = sequence {
|
||||
for (i in 0 until count) {
|
||||
val t = i / (count - 1.0)
|
||||
yield(value(t))
|
||||
}
|
||||
}
|
||||
|
||||
override fun plus(right: LinearRange1D<T>): LinearRange1D<T> =
|
||||
copy(start = start + right.start, end = end + right.end)
|
||||
|
||||
override fun minus(right: LinearRange1D<T>): LinearRange1D<T> =
|
||||
copy(start = start - right.start, end = end - right.end)
|
||||
|
||||
override fun times(scale: Double): LinearRange1D<T> =
|
||||
copy(start = start * scale, end = end * scale)
|
||||
|
||||
override fun div(scale: Double): LinearRange1D<T> =
|
||||
copy(start = start / scale, end = end / scale)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a range from the current linear type instance to the specified end value.
|
||||
*
|
||||
* @param end The end value of the range.
|
||||
* @return A LinearRange that represents the range from the current instance to the specified end value.
|
||||
*/
|
||||
operator fun <T : LinearType<T>> LinearType<T>.rangeTo(end: T): LinearRange1D<T> = LinearRange1D(this as T, end)
|
||||
|
||||
/**
|
||||
* Represents a two-dimensional linear range defined by two one-dimensional linear ranges,
|
||||
* where the `start` and `end` ranges provide endpoints for interpolation.
|
||||
*
|
||||
* This class enables bilinear interpolation between the `start` and `end` ranges
|
||||
* based on parameters `u` and `v`.
|
||||
*
|
||||
* @param T The type of the values being interpolated, constrained by the `LinearType` interface.
|
||||
* @property start The starting one-dimensional linear range.
|
||||
* @property end The ending one-dimensional linear range.
|
||||
*/
|
||||
@JvmRecord
|
||||
data class LinearRange2D<T : LinearType<T>>(val start: LinearRange1D<T>, val end: LinearRange1D<T>) :
|
||||
LinearType<LinearRange2D<T>>,
|
||||
Parametric2D<T> {
|
||||
override fun value(u: Double, v: Double) = start.value(u) * (1.0 - v) + end.value(u) * v
|
||||
|
||||
override fun plus(right: LinearRange2D<T>): LinearRange2D<T> =
|
||||
copy(start = start + right.start, end = end + right.end)
|
||||
|
||||
override fun minus(right: LinearRange2D<T>): LinearRange2D<T> =
|
||||
copy(start = start - right.start, end = end - right.end)
|
||||
|
||||
override fun times(scale: Double): LinearRange2D<T> =
|
||||
copy(start = start * scale, end = end * scale)
|
||||
|
||||
override fun div(scale: Double): LinearRange2D<T> =
|
||||
copy(start = start / scale, end = end / scale)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a `LinearRange2D` instance using this `LinearRange1D` as the starting range
|
||||
* and the specified `end` as the ending range.
|
||||
*
|
||||
* @param end The ending `LinearRange1D` to create a 2D range.
|
||||
* @return A `LinearRange2D` instance representing the range from this starting range to the specified ending range.
|
||||
*/
|
||||
operator fun <T : LinearType<T>> LinearRange1D<T>.rangeTo(end: LinearRange1D<T>): LinearRange2D<T> {
|
||||
return LinearRange2D(this, end)
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a three-dimensional linear range defined by two two-dimensional linear ranges,
|
||||
* where the `start` and `end` ranges provide endpoints for trilinear interpolation.
|
||||
*
|
||||
* This class allows for interpolation across three dimensions using the parameters `u`, `v`, and `w`.
|
||||
*
|
||||
* @param T The type of the values being interpolated, constrained by the `LinearType` interface.
|
||||
* @property start The starting two-dimensional linear range.
|
||||
* @property end The ending two-dimensional linear range.
|
||||
*/
|
||||
@JvmRecord
|
||||
data class LinearRange3D<T : LinearType<T>>(val start: LinearRange2D<T>, val end: LinearRange2D<T>) :
|
||||
LinearType<LinearRange3D<T>>, Parametric3D<T> {
|
||||
override fun value(u: Double, v: Double, w: Double) = start.value(u, v) * (1.0 - w) + end.value(u, v) * w
|
||||
|
||||
override fun plus(right: LinearRange3D<T>): LinearRange3D<T> =
|
||||
copy(start = start + right.start, end = end + right.end)
|
||||
|
||||
override fun minus(right: LinearRange3D<T>): LinearRange3D<T> =
|
||||
copy(start = start - right.start, end = end - right.end)
|
||||
|
||||
override fun times(scale: Double): LinearRange3D<T> =
|
||||
copy(start = start * scale, end = end * scale)
|
||||
|
||||
override fun div(scale: Double): LinearRange3D<T> =
|
||||
copy(start = start / scale, end = end / scale)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a 3D linear range from the current 2D linear range to the specified 2D linear range.
|
||||
*
|
||||
* @param end The ending 2D linear range to define the 3D linear range.
|
||||
* @return A new instance of LinearRange3D representing the range from the current 2D range to the specified end range.
|
||||
*/
|
||||
operator fun <T : LinearType<T>> LinearRange2D<T>.rangeTo(end: LinearRange2D<T>): LinearRange3D<T> =
|
||||
LinearRange3D(this, end)
|
||||
|
||||
/**
|
||||
* Represents a four-dimensional linear range defined by two three-dimensional linear ranges,
|
||||
* providing endpoints for quadrilinear interpolation.
|
||||
*
|
||||
* This class supports interpolation across four dimensions using the parameters `u`, `v`, `w`, and `t`.
|
||||
* The interpolation is computed as a combination of the `start` and `end` LinearRange3D objects:
|
||||
* - The `start` LinearRange3D is weighted by `(1.0 - t)`
|
||||
* - The `end` LinearRange3D is weighted by `t`
|
||||
*
|
||||
* @param T The type of the values being interpolated, constrained by the `LinearType` interface.
|
||||
* @property start The starting three-dimensional linear range.
|
||||
* @property end The ending three-dimensional linear range.
|
||||
*/
|
||||
@JvmRecord
|
||||
data class LinearRange4D<T : LinearType<T>>(val start: LinearRange3D<T>, val end: LinearRange3D<T>) :
|
||||
LinearType<LinearRange4D<T>>,
|
||||
Parametric4D<T> {
|
||||
override fun value(u: Double, v: Double, w: Double, t: Double) =
|
||||
start.value(u, v, w) * (1.0 - t) + end.value(u, v, w) * t
|
||||
|
||||
override fun plus(right: LinearRange4D<T>): LinearRange4D<T> =
|
||||
copy(start = start + right.start, end = end + right.end)
|
||||
|
||||
override fun minus(right: LinearRange4D<T>): LinearRange4D<T> =
|
||||
copy(start = start - right.start, end = end - right.end)
|
||||
|
||||
override fun times(scale: Double): LinearRange4D<T> =
|
||||
copy(start = start * scale, end = end * scale)
|
||||
|
||||
override fun div(scale: Double): LinearRange4D<T> =
|
||||
copy(start = start / scale, end = end / scale)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a LinearRange4D object representing the range between this LinearRange4D instance and the specified end LinearRange3D instance.
|
||||
*
|
||||
* @param end The ending LinearRange3D instance that defines the range.
|
||||
* @return A LinearRange4D object representing the range from this instance to the specified end instance.
|
||||
*/
|
||||
operator fun <T : LinearType<T>> LinearRange3D<T>.rangeTo(end: LinearRange3D<T>): LinearRange4D<T> {
|
||||
return LinearRange4D(this, end)
|
||||
}
|
||||
150
orx-math/src/commonMain/kotlin/simplexrange/SimplexRange.kt
Normal file
150
orx-math/src/commonMain/kotlin/simplexrange/SimplexRange.kt
Normal file
@@ -0,0 +1,150 @@
|
||||
package org.openrndr.extra.math.simplexrange
|
||||
|
||||
import org.openrndr.math.LinearType
|
||||
import org.openrndr.math.Parametric2D
|
||||
import org.openrndr.math.Parametric3D
|
||||
import org.openrndr.math.Parametric4D
|
||||
import kotlin.jvm.JvmRecord
|
||||
|
||||
import kotlin.math.cbrt
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.sqrt
|
||||
|
||||
/**
|
||||
* Transforms a given array of coordinates into an array of coefficients
|
||||
* for use in simplex-based calculations.
|
||||
*
|
||||
* @param b An array of doubles representing coordinates.
|
||||
* The size of this array determines the dimensionality of the input simplex.
|
||||
* @return A new array of doubles representing the transformed coefficients,
|
||||
* with one additional element compared to the input array.
|
||||
*/
|
||||
fun simplexUpscale(b: DoubleArray): DoubleArray {
|
||||
val transformed = DoubleArray(b.size) {
|
||||
b[it].pow(1.0 / (b.size - it))
|
||||
}
|
||||
var m = 1.0
|
||||
val result = DoubleArray(b.size + 1) {
|
||||
val neg = if (it < transformed.size) 1.0 - transformed[it] else 1.0
|
||||
val v = m * neg
|
||||
m *= if (it < transformed.size) transformed[it] else 1.0
|
||||
v
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a 2D simplex range interpolated in a parametric space.
|
||||
* This class defines a triangular range in 2D space, parameterized by three control points `x0`, `x1`, and `x2`.
|
||||
* It implements the `Parametric2D` interface, allowing evaluation of linear combinations
|
||||
* of these control points based on two parameters `u` and `v`.
|
||||
*
|
||||
* @param T The type parameter constrained to types that implement `LinearType<T>`, enabling
|
||||
* operations such as addition, multiplication, and scalar interpolation.
|
||||
* @property x0 The first control point of the simplex.
|
||||
* @property x1 The second control point of the simplex.
|
||||
* @property x2 The third control point of the simplex.
|
||||
*/
|
||||
@JvmRecord
|
||||
data class SimplexRange2D<T : LinearType<T>>(val x0: T, val x1: T, val x2: T) : Parametric2D<T> {
|
||||
override fun value(u: Double, v: Double): T {
|
||||
val r1 = sqrt(u)
|
||||
val r2 = v
|
||||
|
||||
val a = 1 - r1
|
||||
val b = r1 * (1 - r2)
|
||||
val c = r1 * r2
|
||||
return x0 * a + x1 * b + x2 * c
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a 3D parametric simplex range defined by four control points.
|
||||
*
|
||||
* @param T The type of the coordinate values in the 3D space, which must extend LinearType.
|
||||
* @property x0 The first control point defining the simplex.
|
||||
* @property x1 The second control point defining the simplex.
|
||||
* @property x2 The third control point defining the simplex.
|
||||
* @property x3 The fourth control point defining the simplex.
|
||||
*/
|
||||
@JvmRecord
|
||||
data class SimplexRange3D<T : LinearType<T>>(val x0: T, val x1: T, val x2: T, val x3: T) : Parametric3D<T> {
|
||||
override fun value(u: Double, v: Double, w: Double): T {
|
||||
val r1 = cbrt(u)
|
||||
val r2 = sqrt(v)
|
||||
val r3 = w
|
||||
|
||||
val a = 1 - r1
|
||||
val b = r1 * (1 - r2)
|
||||
val c = r1 * r2 * (1 - r3)
|
||||
val d = r1 * r2 * r3
|
||||
return x0 * a + x1 * b + x2 * c + x3 * d
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a 4D parametric simplex range defined by five control points of type `T`.
|
||||
*
|
||||
* This class computes a value within the simplex range based on four parametric inputs (u, v, w, t).
|
||||
* The control points x0, x1, x2, x3, and x4 determine the shape of the simplex, and the resulting value
|
||||
* is calculated as a weighted combination of the control points using barycentric-like coordinates derived
|
||||
* from the parametric inputs.
|
||||
*
|
||||
* The generic type `T` must extend `LinearType<T>`, as the calculation requires linear operations.
|
||||
*
|
||||
* @param T the type of each control point, constrained to types that implement `LinearType`.
|
||||
* @property x0 the first control point of the simplex.
|
||||
* @property x1 the second control point of the simplex.
|
||||
* @property x2 the third control point of the simplex.
|
||||
* @property x3 the fourth control point of the simplex.
|
||||
* @property x4 the fifth control point of the simplex.
|
||||
*/
|
||||
@JvmRecord
|
||||
data class SimplexRange4D<T : LinearType<T>>(val x0: T, val x1: T, val x2: T, val x3: T, val x4: T) : Parametric4D<T> {
|
||||
override fun value(u: Double, v: Double, w: Double, t: Double): T {
|
||||
val r1 = u.pow(1.0 / 4.0)
|
||||
val r2 = cbrt(v)
|
||||
val r3 = sqrt(w)
|
||||
val r4 = t
|
||||
|
||||
val a = 1 - r1
|
||||
val b = r1 * (1 - r2)
|
||||
val c = r1 * r2 * (1 - r3)
|
||||
val d = r1 * r2 * r3 * (1 - r4)
|
||||
val e = r1 * r2 * r3 * r4
|
||||
return x0 * a + x1 * b + x2 * c + x3 * d + x4 * e
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a value defined over an N-dimensional simplex range.
|
||||
*
|
||||
* This class is constructed using a list of elements of a generic type `T` that
|
||||
* conforms to the `LinearType` interface. The `SimplexRangeND` allows evaluating
|
||||
* a value within the simplex defined by these elements, which are scaled and
|
||||
* combined based on a provided set of barycentric coordinates.
|
||||
*
|
||||
* @param T The type of elements in the simplex, which must implement the `LinearType` interface.
|
||||
* @property x The list of elements representing the vertices of the N-dimensional simplex.
|
||||
*/
|
||||
class SimplexRangeND<T: LinearType<T>>(val x: List<T>) {
|
||||
/**
|
||||
* Computes a value determined by the coordinates given in the input array.
|
||||
*
|
||||
* The method uses the `simplexUpscale` function to transform the input array, resulting in a set of
|
||||
* coefficients. These coefficients are then used to calculate a weighted combination of the elements
|
||||
* in the simplex, represented by the `x` property of the class.
|
||||
*
|
||||
* @param u An array of doubles representing the coordinates for the simplex.
|
||||
* The size of the array must be one less than the number of elements in the simplex.
|
||||
* @return A value of type `T` computed as the weighted combination of the simplex elements.
|
||||
*/
|
||||
fun value(u : DoubleArray): T {
|
||||
val b = simplexUpscale(u)
|
||||
var r = x[0] * b [0]
|
||||
for (i in 1 until x.size) {
|
||||
r += x[i] * b[i]
|
||||
}
|
||||
return r
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package linearrangeimport
|
||||
import org.openrndr.math.Vector2
|
||||
import org.openrndr.math.Vector4
|
||||
import org.openrndr.extra.math.linearrange.rangeTo
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class TestLinearRange {
|
||||
val e = 1E-6
|
||||
|
||||
/**
|
||||
* Verifies the interpolation behavior of a one-dimensional linear range.
|
||||
*
|
||||
* This test checks whether the interpolated value computed for a specific parameter (`t`)
|
||||
* within a linear range of two `Vector2` instances falls within a specified range of error tolerance.
|
||||
*/
|
||||
@Test
|
||||
fun testLinearRange1D() {
|
||||
val v0 = Vector2.UNIT_X
|
||||
val v1 = Vector2.UNIT_Y
|
||||
val lr = v0..v1
|
||||
val c = lr.value(0.5)
|
||||
assertTrue(c.x in 0.5 - e..0.5 + e)
|
||||
assertTrue(c.y in 0.5 - e..0.5 + e)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verifies the interpolation behavior of a two-dimensional linear range.
|
||||
*
|
||||
* This test validates that the computed interpolated value within a 2D linear range of `Vector4` instances
|
||||
* falls within an acceptable range of error tolerance. The interpolation is performed using a `LinearRange2D`
|
||||
* created from two 1D linear ranges, which are themselves defined by start and end `Vector4` points.
|
||||
* The test checks the accuracy of the interpolation for the midpoints along both dimensions.
|
||||
*/
|
||||
@Test
|
||||
fun testLinearRange2D() {
|
||||
val v00 = Vector4.UNIT_X
|
||||
val v01 = Vector4.UNIT_Y
|
||||
val lr0 = v00..v01
|
||||
|
||||
val v10 = Vector4.UNIT_Z
|
||||
val v11 = Vector4.UNIT_W
|
||||
val lr1 = v10..v11
|
||||
|
||||
val lr = lr0..lr1
|
||||
|
||||
val c = lr.value(0.5, 0.5)
|
||||
assertTrue(c.x in 0.25 - e..0.25 + e)
|
||||
assertTrue(c.y in 0.25 - e..0.25 + e)
|
||||
assertTrue(c.z in 0.25 - e..0.25 + e)
|
||||
assertTrue(c.w in 0.25 - e..0.25 + e)
|
||||
}
|
||||
}
|
||||
37
orx-math/src/jvmDemo/kotlin/linearrange/DemoLinearRange02.kt
Normal file
37
orx-math/src/jvmDemo/kotlin/linearrange/DemoLinearRange02.kt
Normal file
@@ -0,0 +1,37 @@
|
||||
package linearrange
|
||||
|
||||
import org.openrndr.application
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.draw.isolated
|
||||
import org.openrndr.extra.math.linearrange.rangeTo
|
||||
import org.openrndr.math.Vector2
|
||||
import org.openrndr.shape.Rectangle
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val range = Rectangle.fromCenter(Vector2(36.0, 36.0), 72.0, 18.0)..
|
||||
Rectangle.fromCenter(Vector2(36.0, 36.0), 18.0, 72.0)
|
||||
extend {
|
||||
drawer.fill = ColorRGBa.PINK.opacify(0.9)
|
||||
drawer.stroke = null
|
||||
for (y in 0 until height step 72) {
|
||||
for (x in 0 until width step 72) {
|
||||
val u = cos(seconds + x * 0.007) * 0.5 + 0.5
|
||||
val s = sin(seconds*1.03 + y * 0.0075) * 0.5 + 0.5
|
||||
drawer.isolated {
|
||||
drawer.translate(x.toDouble(), y.toDouble())
|
||||
drawer.rectangle(range.value(u * s))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
41
orx-math/src/jvmDemo/kotlin/linearrange/DemoLinearRange03.kt
Normal file
41
orx-math/src/jvmDemo/kotlin/linearrange/DemoLinearRange03.kt
Normal file
@@ -0,0 +1,41 @@
|
||||
package linearrange
|
||||
|
||||
import org.openrndr.application
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.draw.isolated
|
||||
import org.openrndr.extra.math.linearrange.rangeTo
|
||||
import org.openrndr.math.Vector2
|
||||
import org.openrndr.shape.Rectangle
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val range0 = Rectangle.fromCenter(Vector2(36.0, 36.0), 72.0, 18.0)..
|
||||
Rectangle.fromCenter(Vector2(36.0, 36.0), 18.0, 72.0)
|
||||
val range1 = Rectangle.fromCenter(Vector2(36.0, 0.0), 9.0, 9.0)..
|
||||
Rectangle.fromCenter(Vector2(36.0, 72.0), 9.0, 9.0)
|
||||
|
||||
val range = range0..range1
|
||||
extend {
|
||||
drawer.fill = ColorRGBa.PINK.opacify(0.9)
|
||||
drawer.stroke = null
|
||||
for (y in 0 until height step 72) {
|
||||
for (x in 0 until width step 72) {
|
||||
val u = cos(seconds* 2.0 + x * 0.01) * 0.5 + 0.5
|
||||
val v = sin(seconds * 1.03 + y * 0.01) * 0.5 + 0.5
|
||||
drawer.isolated {
|
||||
drawer.translate(x.toDouble(), y.toDouble())
|
||||
drawer.rectangle(range.value(u, v))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package simplexrange
|
||||
|
||||
import org.openrndr.application
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.draw.DrawPrimitive
|
||||
import org.openrndr.draw.isolated
|
||||
import org.openrndr.extra.camera.Orbital
|
||||
import org.openrndr.extra.meshgenerators.boxMesh
|
||||
import org.openrndr.extra.math.simplexrange.SimplexRange3D
|
||||
import org.openrndr.math.Vector3
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
|
||||
program {
|
||||
val box = boxMesh()
|
||||
extend(Orbital()) {
|
||||
eye = Vector3(1.0, -1.0, 1.0).normalized * 140.0
|
||||
fov = 15.0
|
||||
}
|
||||
extend {
|
||||
val sr = SimplexRange3D(
|
||||
ColorRGBa.PINK.toLinear(),
|
||||
ColorRGBa.RED.toLinear(),
|
||||
ColorRGBa.MAGENTA.toLinear(),
|
||||
ColorRGBa.BLUE.toLinear()
|
||||
)
|
||||
|
||||
for (z in 0 until 20)
|
||||
for (y in 0 until 20)
|
||||
for (x in 0 until 20) {
|
||||
drawer.isolated {
|
||||
drawer.translate(x - 10.0, y - 10.0, z - 10.0)
|
||||
drawer.fill = sr.value(x / 20.0, y / 20.0, z / 20.0)
|
||||
drawer.vertexBuffer(box, DrawPrimitive.TRIANGLES)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,7 @@ include(
|
||||
"orx-image-fit",
|
||||
"orx-kdtree",
|
||||
"orx-jvm:orx-keyframer",
|
||||
"orx-math",
|
||||
"orx-mesh",
|
||||
"orx-mesh-generators",
|
||||
"orx-mesh-noise",
|
||||
|
||||
Reference in New Issue
Block a user