From 710d1e95383f81d1ce5b78447cd66669db152f48 Mon Sep 17 00:00:00 2001 From: Edwin Jakobs Date: Fri, 7 Mar 2025 14:39:09 +0100 Subject: [PATCH] [orx-shade-styles] Improve EllipticalGradient --- .../fills/gradients/EllipticalGradient.kt | 29 ++++++++---- .../kotlin/gradients/DemoGradient01.kt | 2 - .../kotlin/gradients/DemoGradient08.kt | 47 +++++++++++++++++++ 3 files changed, 68 insertions(+), 10 deletions(-) create mode 100644 orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient08.kt diff --git a/orx-shade-styles/src/commonMain/kotlin/fills/gradients/EllipticalGradient.kt b/orx-shade-styles/src/commonMain/kotlin/fills/gradients/EllipticalGradient.kt index e22f5173..0dff4b2b 100644 --- a/orx-shade-styles/src/commonMain/kotlin/fills/gradients/EllipticalGradient.kt +++ b/orx-shade-styles/src/commonMain/kotlin/fills/gradients/EllipticalGradient.kt @@ -6,6 +6,7 @@ import org.openrndr.extra.shaderphrases.sdf.sdEllipsePhrase import org.openrndr.math.CastableToVector4 import org.openrndr.math.Vector2 import org.openrndr.math.Vector4 +import kotlin.math.PI import kotlin.reflect.KClass class EllipticalGradient( @@ -13,6 +14,7 @@ class EllipticalGradient( center: Vector2 = Vector2(0.5, 0.5), radiusX: Double = 1.0, radiusY: Double = 1.0, + rotation: Double = 0.0, colors: Array, points: Array = Array(colors.size) { it / (colors.size - 1.0) }, structure: GradientBaseStructure @@ -27,26 +29,35 @@ class EllipticalGradient( var radiusX: Double by Parameter() var radiusY: Double by Parameter() var center: Vector2 by Parameter() + var rotation: Double by Parameter() init { this.radiusX = radiusX this.radiusY = radiusY this.center = center + this.rotation = rotation } companion object { val gradientFunction = """$sdEllipsePhrase float gradientFunction(vec2 coord) { - if (abs(p_radiusX - p_radiusY) < 1E-4) { - vec2 d0 = coord - p_center; + vec2 d0 = coord - p_center; + d0 = rotate2D(d0, p_rotation); + + float minRadius = min(p_radiusX, p_radiusY); + float maxRadius = max(p_radiusX, p_radiusY); + + if (minRadius < 1E-3) { + return 1.0; + } else if (abs(p_radiusX - p_radiusY) < 1E-4) { + float d0l = length(d0); - float f = d0l / p_radiusX; - return f; + float f = d0l;// / p_radiusX; + return f / p_radiusX; } else { - float maxRadius = min(p_radiusX, p_radiusY); - vec2 d0 = (coord - p_center) / maxRadius; - float f = sdEllipse(d0, vec2(p_radiusX, p_radiusY)/maxRadius ); - float f0 = sdEllipse(vec2(0.0), vec2(p_radiusX, p_radiusY)/maxRadius ); + + float f = sdEllipse(d0, vec2(p_radiusX, p_radiusY) ) / minRadius; + float f0 = sdEllipse(vec2(0.001, 0.001), vec2(p_radiusX, p_radiusY)) / minRadius; f -= f0; return f; } @@ -82,6 +93,7 @@ class EllipticalGradientBuilder(private val gradientBuilder: GradientBuilder< var radiusX = 0.5 var radiusY = 0.5 + var rotation = 0.0 /** * Specifies the focal center point for the radial gradient. * @@ -104,6 +116,7 @@ class EllipticalGradientBuilder(private val gradientBuilder: GradientBuilder< center, radiusX, radiusY, + rotation, colors, stops, gradientBuilder.structure() diff --git a/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient01.kt b/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient01.kt index e4122d09..31b61c0e 100644 --- a/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient01.kt +++ b/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient01.kt @@ -2,8 +2,6 @@ package gradients import org.openrndr.application import org.openrndr.color.ColorRGBa -import org.openrndr.extra.color.spaces.ColorOKLABa -import org.openrndr.extra.color.spaces.toOKLABa import org.openrndr.extra.shadestyles.fills.SpreadMethod import org.openrndr.extra.shadestyles.fills.gradients.gradient import org.openrndr.math.Vector2 diff --git a/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient08.kt b/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient08.kt new file mode 100644 index 00000000..dcb7fffd --- /dev/null +++ b/orx-shade-styles/src/jvmDemo/kotlin/gradients/DemoGradient08.kt @@ -0,0 +1,47 @@ +package gradients + +import org.openrndr.application +import org.openrndr.color.ColorRGBa +import org.openrndr.extra.color.presets.CRIMSON +import org.openrndr.extra.color.presets.DODGER_BLUE +import org.openrndr.extra.color.presets.LIME_GREEN +import org.openrndr.extra.shadestyles.fills.SpreadMethod +import org.openrndr.extra.shadestyles.fills.gradients.gradient +import org.openrndr.extra.shapes.primitives.grid +import org.openrndr.math.Vector2 +import org.openrndr.math.asDegrees +import kotlin.math.atan2 + +fun main() = + application { + configure { + width = 720 + height = 720 + } + program { + extend { + val grid = drawer.bounds.grid(13, 13) + drawer.stroke = null + + for ((y, row) in grid.withIndex()) { + for ((x, cell) in row.withIndex()) { + drawer.shadeStyle = gradient { + stops[0.0] = ColorRGBa.CRIMSON + stops[0.5] = ColorRGBa.DODGER_BLUE + stops[1.0] = ColorRGBa.LIME_GREEN + + spreadMethod = SpreadMethod.REPEAT + elliptic { + val v = Vector2(x-6.0, y-6.0) + rotation = atan2(y- 6.0, x - 6.0).asDegrees + 180.0 + radiusX = 1.0 + radiusY = 1.0 / (1.0 + v.length*0.25) + } + } + drawer.rectangle(cell) + } + } + } + } + } +