[orx-noise] Fix infinite loop in Vector2.uniformRing

This commit is contained in:
Edwin Jakobs
2023-12-15 18:10:31 +01:00
parent 39055254c6
commit 5364cc6eee

View File

@@ -1,52 +1,88 @@
package org.openrndr.extra.noise package org.openrndr.extra.noise
import org.openrndr.math.IntVector2 import org.openrndr.math.*
import org.openrndr.math.Vector2
import org.openrndr.math.Vector3
import org.openrndr.math.Vector4
import org.openrndr.shape.Rectangle import org.openrndr.shape.Rectangle
import kotlin.math.abs
import kotlin.random.Random import kotlin.random.Random
fun random(min: Double = -1.0, max: Double = 1.0, fun random(
random: Random = Random.Default) = min: Double = -1.0, max: Double = 1.0,
random: Random = Random.Default
) =
(random.nextDouble() * (max - min)) + min (random.nextDouble() * (max - min)) + min
fun Int.Companion.uniform(min: Int = -1, max: Int = 2, fun Int.Companion.uniform(
random: Random = Random.Default) = min: Int = -1, max: Int = 2,
random: Random = Random.Default
) =
(random.nextDouble() * (max - min)).toInt() + min (random.nextDouble() * (max - min)).toInt() + min
fun Double.Companion.uniform(min: Double = -1.0, max: Double = 1.0, fun Double.Companion.uniform(
random: Random = Random.Default) = min: Double = -1.0, max: Double = 1.0,
random: Random = Random.Default
) =
(random.nextDouble() * (max - min)) + min (random.nextDouble() * (max - min)) + min
fun Vector2.Companion.uniform(min: Vector2 = -ONE, max: Vector2 = ONE, fun Vector2.Companion.uniform(
random: Random = Random.Default) = min: Vector2 = -ONE, max: Vector2 = ONE,
Vector2(Double.uniform(min.x, max.x, random), random: Random = Random.Default
Double.uniform(min.y, max.y, random)) ) =
Vector2(
Double.uniform(min.x, max.x, random),
Double.uniform(min.y, max.y, random)
)
fun Vector2.Companion.uniform(min: Double = -1.0, max: Double = 1.0, fun Vector2.Companion.uniform(
random: Random = Random.Default) = min: Double = -1.0, max: Double = 1.0,
random: Random = Random.Default
) =
Vector2.uniform(Vector2(min, min), Vector2(max, max), random) Vector2.uniform(Vector2(min, min), Vector2(max, max), random)
fun Vector2.Companion.uniform(rect: Rectangle, fun Vector2.Companion.uniform(
random: Random = Random.Default) = rect: Rectangle,
Vector2.uniform(rect.corner, random: Random = Random.Default
rect.corner + rect.dimensions, random) ) =
Vector2.uniform(
rect.corner,
rect.corner + rect.dimensions, random
)
fun IntVector2.Companion.uniform(min: IntVector2 = IntVector2(-1, -1), fun IntVector2.Companion.uniform(
min: IntVector2 = IntVector2(-1, -1),
max: IntVector2 = IntVector2(2, 2), max: IntVector2 = IntVector2(2, 2),
random: Random = Random.Default) = random: Random = Random.Default
IntVector2(Int.uniform(min.x, max.x, random), ) =
Int.uniform(min.y, max.y, random)) IntVector2(
Int.uniform(min.x, max.x, random),
Int.uniform(min.y, max.y, random)
)
fun IntVector2.Companion.uniform(min: Int = -1, max: Int = 2, fun IntVector2.Companion.uniform(
random: Random = Random.Default) = min: Int = -1, max: Int = 2,
IntVector2.uniform(IntVector2(min, min), random: Random = Random.Default
IntVector2(max, max), random) ) =
IntVector2.uniform(
IntVector2(min, min),
IntVector2(max, max), random
)
fun Vector2.Companion.uniformRing(innerRadius: Double = 0.0, fun Vector2.Companion.uniformRing(
innerRadius: Double = 0.0,
outerRadius: Double = 1.0, outerRadius: Double = 1.0,
random: Random = Random.Default): Vector2 { random: Random = Random.Default
): Vector2 {
require(innerRadius <= outerRadius) {
}
val eps = 1E-6
if ( abs(innerRadius - outerRadius) < eps) {
val angle = Double.uniform(-180.0, 180.0, random)
return Polar(angle, innerRadius).cartesian
} else if (innerRadius < outerRadius) {
while (true) { while (true) {
uniform(-outerRadius, outerRadius, random).let { uniform(-outerRadius, outerRadius, random).let {
val squaredLength = it.squaredLength val squaredLength = it.squaredLength
@@ -55,32 +91,43 @@ fun Vector2.Companion.uniformRing(innerRadius: Double = 0.0,
} }
} }
} }
} else {
error("innerRadius (=$innerRadius) should be less or equal to outerRadius (=$outerRadius)")
}
} }
fun Vector2.Companion.uniforms(count: Int, fun Vector2.Companion.uniforms(
count: Int,
min: Vector2 = -ONE, min: Vector2 = -ONE,
max: Vector2 = ONE, max: Vector2 = ONE,
random: Random = Random.Default): List<Vector2> = random: Random = Random.Default
): List<Vector2> =
List(count) { List(count) {
Vector2.uniform(min, max, random) Vector2.uniform(min, max, random)
} }
fun Vector2.Companion.uniforms(count: Int, fun Vector2.Companion.uniforms(
count: Int,
rect: Rectangle, rect: Rectangle,
random: Random = Random.Default): List<Vector2> = random: Random = Random.Default
): List<Vector2> =
List(count) { Vector2.uniform(rect, random) } List(count) { Vector2.uniform(rect, random) }
fun Vector2.Companion.uniformSequence(rect: Rectangle, fun Vector2.Companion.uniformSequence(
random: Random = Random.Default): Sequence<Vector2> = rect: Rectangle,
random: Random = Random.Default
): Sequence<Vector2> =
sequence { sequence {
while(true) { while (true) {
yield(uniform(rect, random)) yield(uniform(rect, random))
} }
} }
fun Vector2.Companion.uniformsRing(count: Int, fun Vector2.Companion.uniformsRing(
count: Int,
innerRadius: Double = 0.0, outerRadius: Double = 1.0, innerRadius: Double = 0.0, outerRadius: Double = 1.0,
random: Random = Random.Default): List<Vector2> = random: Random = Random.Default
): List<Vector2> =
List(count) { List(count) {
Vector2.uniformRing(innerRadius, outerRadius, random) Vector2.uniformRing(innerRadius, outerRadius, random)
} }
@@ -88,17 +135,23 @@ fun Vector2.Companion.uniformsRing(count: Int,
fun Vector3.Companion.uniform(min: Double = -1.0, max: Double = 1.0, random: Random = Random.Default): Vector3 = fun Vector3.Companion.uniform(min: Double = -1.0, max: Double = 1.0, random: Random = Random.Default): Vector3 =
Vector3.uniform(Vector3(min, min, min), Vector3(max, max, max), random) Vector3.uniform(Vector3(min, min, min), Vector3(max, max, max), random)
fun Vector3.Companion.uniform(min: Vector3 = -ONE, fun Vector3.Companion.uniform(
min: Vector3 = -ONE,
max: Vector3 = ONE, max: Vector3 = ONE,
random: Random = Random.Default): Vector3 { random: Random = Random.Default
return Vector3(Double.uniform(min.x, max.x, random), ): Vector3 {
return Vector3(
Double.uniform(min.x, max.x, random),
Double.uniform(min.y, max.y, random), Double.uniform(min.y, max.y, random),
Double.uniform(min.z, max.z, random)) Double.uniform(min.z, max.z, random)
)
} }
fun Vector3.Companion.uniformRing(innerRadius: Double = 0.0, fun Vector3.Companion.uniformRing(
innerRadius: Double = 0.0,
outerRadius: Double = 1.0, outerRadius: Double = 1.0,
random: Random = Random.Default): Vector3 { random: Random = Random.Default
): Vector3 {
while (true) { while (true) {
uniform(-outerRadius, outerRadius, random).let { uniform(-outerRadius, outerRadius, random).let {
val squaredLength = it.squaredLength val squaredLength = it.squaredLength
@@ -109,26 +162,32 @@ fun Vector3.Companion.uniformRing(innerRadius: Double = 0.0,
} }
} }
fun Vector3.Companion.uniforms(count: Int, fun Vector3.Companion.uniforms(
count: Int,
min: Double = -1.0, min: Double = -1.0,
max: Double = 1.0, max: Double = 1.0,
random: Random = Random.Default): List<Vector3> = random: Random = Random.Default
): List<Vector3> =
List(count) { List(count) {
Vector3.uniform(min, max, random) Vector3.uniform(min, max, random)
} }
fun Vector3.Companion.uniforms(count: Int, fun Vector3.Companion.uniforms(
count: Int,
min: Vector3 = -ONE, min: Vector3 = -ONE,
max: Vector3 = ONE, max: Vector3 = ONE,
random: Random = Random.Default): List<Vector3> = random: Random = Random.Default
): List<Vector3> =
List(count) { List(count) {
Vector3.uniform(min, max, random) Vector3.uniform(min, max, random)
} }
fun Vector3.Companion.uniformsRing(count: Int, fun Vector3.Companion.uniformsRing(
count: Int,
innerRadius: Double = 0.0, outerRadius: Double = 1.0, innerRadius: Double = 0.0, outerRadius: Double = 1.0,
random: Random = Random.Default): List<Vector3> = random: Random = Random.Default
): List<Vector3> =
List(count) { List(count) {
Vector3.uniformRing(innerRadius, outerRadius, random) Vector3.uniformRing(innerRadius, outerRadius, random)
} }
@@ -138,15 +197,19 @@ fun Vector4.Companion.uniform(min: Double = -1.0, max: Double = 1.0, random: Ran
Vector4.uniform(Vector4(min, min, min, min), Vector4(max, max, max, max), random) Vector4.uniform(Vector4(min, min, min, min), Vector4(max, max, max, max), random)
fun Vector4.Companion.uniform(min: Vector4 = -ONE, max: Vector4 = ONE, random: Random = Random.Default): Vector4 { fun Vector4.Companion.uniform(min: Vector4 = -ONE, max: Vector4 = ONE, random: Random = Random.Default): Vector4 {
return Vector4(Double.uniform(min.x, max.x, random), return Vector4(
Double.uniform(min.x, max.x, random),
Double.uniform(min.y, max.y, random), Double.uniform(min.y, max.y, random),
Double.uniform(min.z, max.z, random), Double.uniform(min.z, max.z, random),
Double.uniform(min.w, max.w, random)) Double.uniform(min.w, max.w, random)
)
} }
fun Vector4.Companion.uniformRing(innerRadius: Double = 0.0, fun Vector4.Companion.uniformRing(
innerRadius: Double = 0.0,
outerRadius: Double = 1.0, outerRadius: Double = 1.0,
random: Random = Random.Default): Vector4 { random: Random = Random.Default
): Vector4 {
while (true) { while (true) {
uniform(-outerRadius, outerRadius, random).let { uniform(-outerRadius, outerRadius, random).let {
val squaredLength = it.squaredLength val squaredLength = it.squaredLength