From f84f5d4b9379eb00a0f478fe6131c23f173f717b Mon Sep 17 00:00:00 2001 From: Edwin Jakobs Date: Mon, 24 Apr 2023 22:49:49 +0200 Subject: [PATCH] [orx-delegate-magic] Add more magic --- orx-delegate-magic/build.gradle.kts | 3 +- .../kotlin/aggregation/Aggregators.kt | 39 ++++++++++++++++++ .../kotlin/aggregation/ListAggregation.kt | 37 +++++++++++++++++ .../kotlin/difference/PropertyDifferencer.kt | 30 ++++++++++++++ .../src/jvmDemo/kotlin/DemoDifferencing01.kt | 40 +++++++++++++++++++ .../src/jvmDemo/kotlin/DemoSpring01.kt | 1 - 6 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 orx-delegate-magic/src/commonMain/kotlin/aggregation/Aggregators.kt create mode 100644 orx-delegate-magic/src/commonMain/kotlin/aggregation/ListAggregation.kt create mode 100644 orx-delegate-magic/src/commonMain/kotlin/difference/PropertyDifferencer.kt create mode 100644 orx-delegate-magic/src/jvmDemo/kotlin/DemoDifferencing01.kt diff --git a/orx-delegate-magic/build.gradle.kts b/orx-delegate-magic/build.gradle.kts index b104cf60..45dcee13 100644 --- a/orx-delegate-magic/build.gradle.kts +++ b/orx-delegate-magic/build.gradle.kts @@ -18,7 +18,8 @@ kotlin { @Suppress("UNUSED_VARIABLE") val jvmDemo by getting { dependencies { - implementation(project(":orx-shapes")) + implementation(project(":orx-delegate-magic")) + implementation(project(":orx-jvm:orx-gui")) } } } diff --git a/orx-delegate-magic/src/commonMain/kotlin/aggregation/Aggregators.kt b/orx-delegate-magic/src/commonMain/kotlin/aggregation/Aggregators.kt new file mode 100644 index 00000000..c4dea4c6 --- /dev/null +++ b/orx-delegate-magic/src/commonMain/kotlin/aggregation/Aggregators.kt @@ -0,0 +1,39 @@ +@file:Suppress("PackageDirectoryMismatch") + +package org.openrndr.extra.delegatemagic.aggregation + +import kotlin.math.abs + +fun List.maxMag(): Double { + if (isEmpty()) { + error("list is empty") + } + var maxMag = Double.NEGATIVE_INFINITY + var maxMagWithSign = 0.0 + + for (i in indices) { + val a = abs(this[i]) + if (a > maxMag) { + maxMag = a + maxMagWithSign = this[i] + } + } + return maxMagWithSign +} + +fun List.minMag(): Double { + if (isEmpty()) { + error("list is empty") + } + var minMag = Double.POSITIVE_INFINITY + var minMagWithSign = 0.0 + + for (i in indices) { + val a = abs(this[i]) + if (a < minMag) { + minMag = a + minMagWithSign = this[i] + } + } + return minMagWithSign +} \ No newline at end of file diff --git a/orx-delegate-magic/src/commonMain/kotlin/aggregation/ListAggregation.kt b/orx-delegate-magic/src/commonMain/kotlin/aggregation/ListAggregation.kt new file mode 100644 index 00000000..fa0f5406 --- /dev/null +++ b/orx-delegate-magic/src/commonMain/kotlin/aggregation/ListAggregation.kt @@ -0,0 +1,37 @@ +@file:Suppress("PackageDirectoryMismatch") + +package org.openrndr.extra.delegatemagic.aggregation + +import org.openrndr.Clock +import kotlin.reflect.KProperty +import kotlin.reflect.KProperty0 + +class ListPropertyAggregation( + private val clock: Clock, + private val property: KProperty0>, + val aggregationFunction: (List) -> R +) { + private var output: R? = null + private var lastTime: Double? = null + + operator fun getValue(any: Any?, property: KProperty<*>): R { + if (lastTime != null) { + val dt = clock.seconds - lastTime!! + if (dt > 1E-10) { + output = aggregationFunction(this.property.get()) + } + } else { + output = aggregationFunction(this.property.get()) + } + + lastTime = clock.seconds + return output!! + } +} + +fun Clock.aggregating( + property: KProperty0>, + aggregationFunction: (List) -> R +): ListPropertyAggregation { + return ListPropertyAggregation(this, property, aggregationFunction) +} \ No newline at end of file diff --git a/orx-delegate-magic/src/commonMain/kotlin/difference/PropertyDifferencer.kt b/orx-delegate-magic/src/commonMain/kotlin/difference/PropertyDifferencer.kt new file mode 100644 index 00000000..82a3e40d --- /dev/null +++ b/orx-delegate-magic/src/commonMain/kotlin/difference/PropertyDifferencer.kt @@ -0,0 +1,30 @@ +package difference + +import org.openrndr.Clock +import kotlin.reflect.KProperty +import kotlin.reflect.KProperty0 + +class DoublePropertyDifferencer( + private val clock: Clock, + private val property: KProperty0, +) { + private var lastValue: Double? = null + private var output: Double? = null + private var lastTime: Double? = null + operator fun getValue(any: Any?, property: KProperty<*>): Double { + if (lastTime != null) { + val dt = clock.seconds - lastTime!! + if (dt > 1E-10) { + output = this.property.get() - lastValue!! + lastValue = this.property.get() + } + } else { + lastValue = this.property.get() + output = lastValue!! - lastValue!! + } + lastTime = clock.seconds + return output ?: error("no value") + } +} + +fun Clock.differencing(property: KProperty0) = DoublePropertyDifferencer(this, property) diff --git a/orx-delegate-magic/src/jvmDemo/kotlin/DemoDifferencing01.kt b/orx-delegate-magic/src/jvmDemo/kotlin/DemoDifferencing01.kt new file mode 100644 index 00000000..a333d624 --- /dev/null +++ b/orx-delegate-magic/src/jvmDemo/kotlin/DemoDifferencing01.kt @@ -0,0 +1,40 @@ +import difference.differencing +import org.openrndr.application +import org.openrndr.color.ColorRGBa +import org.openrndr.extra.delegatemagic.aggregation.aggregating +import org.openrndr.extra.delegatemagic.aggregation.maxMag +import org.openrndr.extra.delegatemagic.tracking.tracking +import org.openrndr.extra.gui.GUI +import org.openrndr.extra.parameters.DoubleParameter +import org.openrndr.math.Vector2 + +fun main() { + application { + program { + val gui = GUI() + + val state = object { + @DoubleParameter("radius", 0.0, 200.0) + var radius = 100.0 + + val difference by differencing(::radius) + val differenceHistory by tracking(::difference) + val differenceMax by aggregating(::differenceHistory) { + it.maxMag() + } + } + + gui.add(state, "state") + + extend(gui) + extend { + drawer.circle(drawer.bounds.center, state.radius) + drawer.stroke = ColorRGBa.GREEN + drawer.lineSegment(drawer.bounds.center, drawer.bounds.center + Vector2(state.difference, 0.0)) + drawer.translate(0.0, 4.0) + drawer.stroke = ColorRGBa.BLUE + drawer.lineSegment(drawer.bounds.center, drawer.bounds.center + Vector2(state.differenceMax, 0.0)) + } + } + } +} \ No newline at end of file diff --git a/orx-delegate-magic/src/jvmDemo/kotlin/DemoSpring01.kt b/orx-delegate-magic/src/jvmDemo/kotlin/DemoSpring01.kt index 91072c4d..533adddf 100644 --- a/orx-delegate-magic/src/jvmDemo/kotlin/DemoSpring01.kt +++ b/orx-delegate-magic/src/jvmDemo/kotlin/DemoSpring01.kt @@ -1,6 +1,5 @@ import org.openrndr.application import org.openrndr.extra.delegatemagic.dynamics.springForcing -import org.openrndr.extra.delegatemagic.smoothing.smoothing import kotlin.random.Random fun main() = application {