[orx-color, orx-fx] turbo_colormap and spectral_zucconi6 provided as shader phrases (#338)
This commit is contained in:
91
orx-color/src/commonMain/kotlin/colormaps/ColormapPhrases.kt
Normal file
91
orx-color/src/commonMain/kotlin/colormaps/ColormapPhrases.kt
Normal file
@@ -0,0 +1,91 @@
|
||||
package org.openrndr.extra.color.colormaps
|
||||
|
||||
import org.openrndr.extra.shaderphrases.ShaderPhrase
|
||||
import org.openrndr.extra.shaderphrases.ShaderPhraseBook
|
||||
|
||||
/**
|
||||
* Colormaps represent a class of functions taking a value in the range `0.0..1.0` and returning particular RGB color
|
||||
* values. Colormaps can be used in data visualization for representing additional information/dimension of the data
|
||||
* e.g:
|
||||
* - depth
|
||||
* - elevation
|
||||
* - heat
|
||||
*
|
||||
* Note: the [ShaderPhrase] GLSL functions gathered in this [ShaderPhraseBook] also have respective Kotlin
|
||||
* implementations.
|
||||
*
|
||||
* @see org.openrndr.extra.color.colormaps.turboColormap
|
||||
* @see org.openrndr.extra.color.colormaps.spectralZucconi6
|
||||
*/
|
||||
object ColormapPhraseBook : ShaderPhraseBook("colormap") {
|
||||
|
||||
// Copyright 2019 Google LLC.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
/**
|
||||
* Polynomial approximation in GLSL for the Turbo colormap.
|
||||
*
|
||||
* See [Turbo, An Improved Rainbow Colormap for Visualization](https://research.google/blog/turbo-an-improved-rainbow-colormap-for-visualization/),
|
||||
* [the source of this code](https://gist.github.com/mikhailov-work/0d177465a8151eb6ede1768d51d476c7),
|
||||
*
|
||||
* @author Anton Mikhailov (mikhailov@google.com) - Colormap Design
|
||||
* @author Ruofei Du (ruofei@google.com) - GLSL Approximation
|
||||
* @see org.openrndr.extra.color.colormaps.turboColormap
|
||||
*/
|
||||
val turboColormap = ShaderPhrase("""
|
||||
|vec3 turbo_colormap(in float x) {
|
||||
| const vec4 kRedVec4 = vec4(0.13572138, 4.61539260, -42.66032258, 132.13108234);
|
||||
| const vec4 kGreenVec4 = vec4(0.09140261, 2.19418839, 4.84296658, -14.18503333);
|
||||
| const vec4 kBlueVec4 = vec4(0.10667330, 12.64194608, -60.58204836, 110.36276771);
|
||||
| const vec2 kRedVec2 = vec2(-152.94239396, 59.28637943);
|
||||
| const vec2 kGreenVec2 = vec2(4.27729857, 2.82956604);
|
||||
| const vec2 kBlueVec2 = vec2(-89.90310912, 27.34824973);
|
||||
|
|
||||
| x = clamp(x, 0.0, 1.0);
|
||||
| vec4 v4 = vec4( 1.0, x, x * x, x * x * x);
|
||||
| vec2 v2 = v4.zw * v4.z;
|
||||
| return vec3(
|
||||
| dot(v4, kRedVec4) + dot(v2, kRedVec2),
|
||||
| dot(v4, kGreenVec4) + dot(v2, kGreenVec2),
|
||||
| dot(v4, kBlueVec4) + dot(v2, kBlueVec2)
|
||||
| );
|
||||
|}""".trimMargin())
|
||||
|
||||
/**
|
||||
* Accurate spectral colormap developed by Alan Zucconi.
|
||||
*
|
||||
* See [Improving the Rainbow](https://www.alanzucconi.com/2017/07/15/improving-the-rainbow/) article,
|
||||
* [the source of this code](https://www.shadertoy.com/view/ls2Bz1)
|
||||
*
|
||||
* @author Alan Zucconi
|
||||
* @see org.openrndr.extra.color.colormaps.spectralZucconi6
|
||||
*/
|
||||
val spectralZucconi6 = ShaderPhrase("""
|
||||
|#pragma import colormap.bump3y
|
||||
|
|
||||
|vec3 spectral_zucconi6(in float x) {
|
||||
|
|
||||
| const vec3 c1 = vec3(3.54585104, 2.93225262, 2.41593945);
|
||||
| const vec3 x1 = vec3(0.69549072, 0.49228336, 0.27699880);
|
||||
| const vec3 y1 = vec3(0.02312639, 0.15225084, 0.52607955);
|
||||
|
|
||||
| const vec3 c2 = vec3(3.90307140, 3.21182957, 3.96587128);
|
||||
| const vec3 x2 = vec3(0.11748627, 0.86755042, 0.66077860);
|
||||
| const vec3 y2 = vec3(0.84897130, 0.88445281, 0.73949448);
|
||||
|
|
||||
| return
|
||||
| bump3y(c1 * (x - x1), y1) +
|
||||
| bump3y(c2 * (x - x2), y2) ;
|
||||
|}""".trimMargin())
|
||||
|
||||
/**
|
||||
* A function used internally by [spectralZucconi6].
|
||||
*
|
||||
* @author Alan Zucconi
|
||||
*/
|
||||
val bump3y = ShaderPhrase("""
|
||||
|vec3 bump3y(in vec3 x, in vec3 yoffset) {
|
||||
| vec3 y = vec3(1.0) - x * x;
|
||||
| return clamp(y - yoffset, vec3(0.0), vec3(1.0));
|
||||
|}""".trimMargin())
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.openrndr.extra.color.colormaps
|
||||
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.math.Vector3
|
||||
import org.openrndr.math.saturate
|
||||
|
||||
/**
|
||||
* Accurate spectral colormap developed by Alan Zucconi.
|
||||
*
|
||||
* @see spectralZucconi6Vector
|
||||
* @see ColormapPhraseBook.spectralZucconi6
|
||||
*/
|
||||
fun spectralZucconi6(
|
||||
x: Double
|
||||
): ColorRGBa = ColorRGBa.fromVector(
|
||||
spectralZucconi6Vector(x)
|
||||
)
|
||||
|
||||
/**
|
||||
* Accurate spectral colormap developed by Alan Zucconi.
|
||||
*
|
||||
* @see ColormapPhraseBook.spectralZucconi6
|
||||
*/
|
||||
fun spectralZucconi6Vector(x: Double): Vector3 {
|
||||
val v = Vector3(x)
|
||||
return bump3y(c1 * (v - x1), y1) + bump3y(c2 * (v - x2), y2)
|
||||
}
|
||||
|
||||
private fun bump3y(
|
||||
x: Vector3,
|
||||
yOffset: Vector3
|
||||
) = (Vector3.ONE - x * x - yOffset).saturate()
|
||||
|
||||
private val c1 = Vector3(3.54585104, 2.93225262, 2.41593945)
|
||||
private val x1 = Vector3(0.69549072, 0.49228336, 0.27699880)
|
||||
private val y1 = Vector3(0.02312639, 0.15225084, 0.52607955)
|
||||
|
||||
private val c2 = Vector3(3.90307140, 3.21182957, 3.96587128)
|
||||
private val x2 = Vector3(0.11748627, 0.86755042, 0.66077860)
|
||||
private val y2 = Vector3(0.84897130, 0.88445281, 0.73949448)
|
||||
39
orx-color/src/commonMain/kotlin/colormaps/TurboColormap.kt
Normal file
39
orx-color/src/commonMain/kotlin/colormaps/TurboColormap.kt
Normal file
@@ -0,0 +1,39 @@
|
||||
package org.openrndr.extra.color.colormaps
|
||||
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.math.*
|
||||
|
||||
/**
|
||||
* Polynomial approximation in GLSL for the Turbo colormap.
|
||||
*
|
||||
* @see turboColormapVector
|
||||
* @see ColormapPhraseBook.turboColormap
|
||||
*/
|
||||
fun turboColormap(
|
||||
x: Double
|
||||
): ColorRGBa = ColorRGBa.fromVector(
|
||||
turboColormapVector(x)
|
||||
)
|
||||
|
||||
/**
|
||||
* Polynomial approximation in GLSL for the Turbo colormap.
|
||||
*
|
||||
* @see ColormapPhraseBook.turboColormap
|
||||
*/
|
||||
fun turboColormapVector(x: Double): Vector3 {
|
||||
val v = saturate(x)
|
||||
val v4 = Vector4( 1.0, v, v * v, v * v * v)
|
||||
val v2 = Vector2(v4.z, v4.w) * v4.z
|
||||
return Vector3(
|
||||
v4.dot(kRedVec4) + v2.dot(kRedVec2),
|
||||
v4.dot(kGreenVec4) + v2.dot(kGreenVec2),
|
||||
v4.dot(kBlueVec4) + v2.dot(kBlueVec2)
|
||||
)
|
||||
}
|
||||
|
||||
private val kRedVec4 = Vector4(0.13572138, 4.61539260, -42.66032258, 132.13108234)
|
||||
private val kGreenVec4 = Vector4(0.09140261, 2.19418839, 4.84296658, -14.18503333)
|
||||
private val kBlueVec4 = Vector4(0.10667330, 12.64194608, -60.58204836, 110.36276771)
|
||||
private val kRedVec2 = Vector2(-152.94239396, 59.28637943)
|
||||
private val kGreenVec2 = Vector2(4.27729857, 2.82956604)
|
||||
private val kBlueVec2 = Vector2(-89.90310912, 27.34824973)
|
||||
5
orx-color/src/commonTest/kotlin/ColorTest.kt
Normal file
5
orx-color/src/commonTest/kotlin/ColorTest.kt
Normal file
@@ -0,0 +1,5 @@
|
||||
// keeping this file here will stop IntelliJ from showing warning in nested relative packages
|
||||
/**
|
||||
* orx-color
|
||||
*/
|
||||
package org.openrndr.extra.color
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.openrndr.extra.color.colormaps
|
||||
|
||||
import io.kotest.matchers.shouldBe
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.color.Linearity
|
||||
import org.openrndr.math.Vector3
|
||||
import kotlin.test.Test
|
||||
|
||||
class TestSpectralZucconi6Colormap {
|
||||
|
||||
@Test
|
||||
fun testSpectralZucconi6Vector() {
|
||||
spectralZucconi6Vector(0.0) shouldBe Vector3(0.0, 0.0, 0.026075309353279508)
|
||||
spectralZucconi6Vector(0.5) shouldBe Vector3(0.49637374891706215, 0.8472371726323733, 0.18366091774095827)
|
||||
spectralZucconi6Vector(1.0) shouldBe Vector3(0.0, 0.0, 0.0)
|
||||
spectralZucconi6Vector(-0.1) shouldBe Vector3(0.0, 0.0, 0.0)
|
||||
spectralZucconi6Vector(1.1) shouldBe Vector3(0.0, 0.0, 0.0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSpectralZucconi6() {
|
||||
spectralZucconi6(0.0) shouldBe ColorRGBa(0.0, 0.0, 0.026075309353279508, linearity = Linearity.SRGB)
|
||||
spectralZucconi6(0.5) shouldBe ColorRGBa(0.49637374891706215, 0.8472371726323733, 0.18366091774095827, linearity = Linearity.SRGB)
|
||||
spectralZucconi6(1.0) shouldBe ColorRGBa(0.0, 0.0, 0.0, linearity = Linearity.SRGB)
|
||||
spectralZucconi6(-0.1) shouldBe ColorRGBa(0.0, 0.0, 0.0, linearity = Linearity.SRGB)
|
||||
spectralZucconi6(1.1) shouldBe ColorRGBa(0.0, 0.0, 0.0, linearity = Linearity.SRGB)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.openrndr.extra.color.colormaps
|
||||
|
||||
import io.kotest.matchers.shouldBe
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.color.Linearity
|
||||
import org.openrndr.math.Vector3
|
||||
import kotlin.test.Test
|
||||
|
||||
class TestTurboColormap {
|
||||
|
||||
@Test
|
||||
fun testTurboColormapVector() {
|
||||
turboColormapVector(0.0) shouldBe Vector3(0.13572138, 0.09140261, 0.1066733)
|
||||
turboColormapVector(0.5) shouldBe Vector3(0.5885220621875007, 0.981864383125, 0.31316869781249856)
|
||||
turboColormapVector(1.0) shouldBe Vector3(0.5658592099999993, 0.05038885999999998, -0.025520659999997974)
|
||||
turboColormapVector(-0.1) shouldBe Vector3(0.13572138, 0.09140261, 0.1066733)
|
||||
turboColormapVector(1.1) shouldBe Vector3(0.5658592099999993, 0.05038885999999998, -0.025520659999997974)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTurboColormap() {
|
||||
turboColormap(0.0) shouldBe ColorRGBa(0.13572138, 0.09140261, 0.1066733, linearity = Linearity.SRGB)
|
||||
turboColormap(0.5) shouldBe ColorRGBa(0.5885220621875007, 0.981864383125, 0.31316869781249856, linearity = Linearity.SRGB)
|
||||
turboColormap(1.0) shouldBe ColorRGBa(0.5658592099999993, 0.05038885999999998, -0.025520659999997974, linearity = Linearity.SRGB)
|
||||
turboColormap(-0.1) shouldBe ColorRGBa(0.13572138, 0.09140261, 0.1066733, linearity = Linearity.SRGB)
|
||||
turboColormap(1.1) shouldBe ColorRGBa(0.5658592099999993, 0.05038885999999998, -0.025520659999997974, linearity = Linearity.SRGB)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package spaces
|
||||
package org.openrndr.extra.color.spaces
|
||||
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.color.spaces.toHSLUVa
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package spaces
|
||||
package org.openrndr.extra.color.spaces
|
||||
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.color.spaces.toOKHSLa
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package spaces
|
||||
package org.openrndr.extra.color.spaces
|
||||
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.color.spaces.toOKHSLa
|
||||
import org.openrndr.extra.color.spaces.toOKHSVa
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package spaces
|
||||
package org.openrndr.extra.color.spaces
|
||||
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.color.spaces.OKLCH
|
||||
import org.openrndr.extra.color.spaces.toOKLCHa
|
||||
import org.openrndr.extra.color.tools.chroma
|
||||
import org.openrndr.extra.color.tools.withLuminosity
|
||||
import kotlin.test.Test
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
package spaces
|
||||
package org.openrndr.extra.color.spaces
|
||||
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.color.spaces.hueToX
|
||||
import org.openrndr.extra.color.spaces.toHSLUVa
|
||||
import org.openrndr.extra.color.spaces.toXSLUVa
|
||||
import org.openrndr.extra.color.spaces.xToHue
|
||||
import kotlin.math.abs
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
package tools
|
||||
package org.openrndr.extra.color.tools
|
||||
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.color.spaces.toOKLCHa
|
||||
import org.openrndr.extra.color.tools.findMaxChroma
|
||||
import org.openrndr.extra.color.tools.isOutOfGamut
|
||||
import kotlin.test.Test
|
||||
|
||||
class TestChromaColorExtensions {
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
package tools
|
||||
package org.openrndr.extra.color.tools
|
||||
|
||||
import org.openrndr.color.*
|
||||
import org.openrndr.extra.color.spaces.*
|
||||
import org.openrndr.extra.color.tools.mixedWith
|
||||
import org.openrndr.extra.color.tools.saturate
|
||||
import org.openrndr.extra.color.tools.shiftHue
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
22
orx-color/src/jvmDemo/kotlin/DemoSpectralZucconiColormap.kt
Normal file
22
orx-color/src/jvmDemo/kotlin/DemoSpectralZucconiColormap.kt
Normal file
@@ -0,0 +1,22 @@
|
||||
import org.openrndr.application
|
||||
import org.openrndr.extra.color.colormaps.spectralZucconi6
|
||||
import org.openrndr.extra.noise.fastFloor
|
||||
import kotlin.math.sin
|
||||
|
||||
fun main() = application {
|
||||
program {
|
||||
extend {
|
||||
drawer.stroke = null
|
||||
val stripeCount = 32 + (sin(seconds) * 16.0).fastFloor()
|
||||
repeat(stripeCount) { i ->
|
||||
drawer.fill = spectralZucconi6(i / stripeCount.toDouble())
|
||||
drawer.rectangle(
|
||||
x = i * width / stripeCount.toDouble(),
|
||||
y = 0.0,
|
||||
width = width / stripeCount.toDouble(),
|
||||
height = height.toDouble(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import org.openrndr.application
|
||||
import org.openrndr.draw.shadeStyle
|
||||
import org.openrndr.extra.color.colormaps.ColormapPhraseBook
|
||||
import org.openrndr.extra.shaderphrases.preprocess
|
||||
|
||||
fun main() = application {
|
||||
program {
|
||||
ColormapPhraseBook.register()
|
||||
val style = shadeStyle {
|
||||
fragmentPreamble = "#pragma import colormap.spectral_zucconi6".preprocess()
|
||||
fragmentTransform = "x_fill.rgb = spectral_zucconi6(c_boundsPosition.x);"
|
||||
}
|
||||
extend {
|
||||
drawer.run {
|
||||
shadeStyle = style
|
||||
rectangle(bounds)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import org.openrndr.application
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.draw.shadeStyle
|
||||
import org.openrndr.extra.color.colormaps.ColormapPhraseBook
|
||||
import org.openrndr.extra.color.colormaps.spectralZucconi6
|
||||
import org.openrndr.extra.shaderphrases.preprocess
|
||||
import org.openrndr.math.Vector2
|
||||
|
||||
fun main() = application {
|
||||
program {
|
||||
ColormapPhraseBook.register()
|
||||
val backgroundStyle = shadeStyle {
|
||||
fragmentPreamble = "#pragma import colormap.spectral_zucconi6".preprocess()
|
||||
fragmentTransform = "x_fill.rgb = spectral_zucconi6(c_boundsPosition.x);"
|
||||
}
|
||||
fun getColormapPoints(
|
||||
block: ColorRGBa.() -> Double
|
||||
) = List(width) { x ->
|
||||
Vector2(
|
||||
x = x.toDouble(),
|
||||
y = height.toDouble()
|
||||
- block(spectralZucconi6(x / width.toDouble()))
|
||||
* height.toDouble()
|
||||
)
|
||||
}
|
||||
val redPoints = getColormapPoints { r }
|
||||
val greenPoints = getColormapPoints { g }
|
||||
val bluePoints = getColormapPoints { b }
|
||||
extend {
|
||||
drawer.run {
|
||||
shadeStyle = backgroundStyle
|
||||
rectangle(bounds)
|
||||
shadeStyle = null
|
||||
strokeWeight = 1.0
|
||||
stroke = ColorRGBa.RED
|
||||
lineStrip(redPoints)
|
||||
stroke = ColorRGBa.GREEN
|
||||
lineStrip(greenPoints)
|
||||
stroke = ColorRGBa.BLUE
|
||||
lineStrip(bluePoints)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
22
orx-color/src/jvmDemo/kotlin/DemoTurboColormap.kt
Normal file
22
orx-color/src/jvmDemo/kotlin/DemoTurboColormap.kt
Normal file
@@ -0,0 +1,22 @@
|
||||
import org.openrndr.application
|
||||
import org.openrndr.extra.color.colormaps.turboColormap
|
||||
import org.openrndr.extra.noise.fastFloor
|
||||
import kotlin.math.sin
|
||||
|
||||
fun main() = application {
|
||||
program {
|
||||
extend {
|
||||
drawer.stroke = null
|
||||
val stripeCount = 32 + (sin(seconds) * 16.0).fastFloor()
|
||||
repeat(stripeCount) { i ->
|
||||
drawer.fill = turboColormap(i / stripeCount.toDouble())
|
||||
drawer.rectangle(
|
||||
x = i * width / stripeCount.toDouble(),
|
||||
y = 0.0,
|
||||
width = width / stripeCount.toDouble(),
|
||||
height = height.toDouble(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
20
orx-color/src/jvmDemo/kotlin/DemoTurboColormapPhrase.kt
Normal file
20
orx-color/src/jvmDemo/kotlin/DemoTurboColormapPhrase.kt
Normal file
@@ -0,0 +1,20 @@
|
||||
import org.openrndr.application
|
||||
import org.openrndr.draw.shadeStyle
|
||||
import org.openrndr.extra.color.colormaps.ColormapPhraseBook
|
||||
import org.openrndr.extra.shaderphrases.preprocess
|
||||
|
||||
fun main() = application {
|
||||
program {
|
||||
ColormapPhraseBook.register()
|
||||
val style = shadeStyle {
|
||||
fragmentPreamble = "#pragma import colormap.turbo_colormap".preprocess()
|
||||
fragmentTransform = "x_fill.rgb = turbo_colormap(c_boundsPosition.x);"
|
||||
}
|
||||
extend {
|
||||
drawer.run {
|
||||
shadeStyle = style
|
||||
rectangle(bounds)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
44
orx-color/src/jvmDemo/kotlin/DemoTurboColormapPlot.kt
Normal file
44
orx-color/src/jvmDemo/kotlin/DemoTurboColormapPlot.kt
Normal file
@@ -0,0 +1,44 @@
|
||||
import org.openrndr.application
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.draw.shadeStyle
|
||||
import org.openrndr.extra.color.colormaps.ColormapPhraseBook
|
||||
import org.openrndr.extra.color.colormaps.turboColormap
|
||||
import org.openrndr.extra.shaderphrases.preprocess
|
||||
import org.openrndr.math.Vector2
|
||||
|
||||
fun main() = application {
|
||||
program {
|
||||
ColormapPhraseBook.register()
|
||||
val backgroundStyle = shadeStyle {
|
||||
fragmentPreamble = "#pragma import colormap.turbo_colormap".preprocess()
|
||||
fragmentTransform = "x_fill.rgb = turbo_colormap(c_boundsPosition.x);"
|
||||
}
|
||||
fun getColormapPoints(
|
||||
block: ColorRGBa.() -> Double
|
||||
) = List(width) { x ->
|
||||
Vector2(
|
||||
x = x.toDouble(),
|
||||
y = height.toDouble()
|
||||
- block(turboColormap(x / width.toDouble()))
|
||||
* height.toDouble()
|
||||
)
|
||||
}
|
||||
val redPoints = getColormapPoints { r }
|
||||
val greenPoints = getColormapPoints { g }
|
||||
val bluePoints = getColormapPoints { b }
|
||||
extend {
|
||||
drawer.run {
|
||||
shadeStyle = backgroundStyle
|
||||
rectangle(bounds)
|
||||
shadeStyle = null
|
||||
strokeWeight = 1.0
|
||||
stroke = ColorRGBa.RED
|
||||
lineStrip(redPoints)
|
||||
stroke = ColorRGBa.GREEN
|
||||
lineStrip(greenPoints)
|
||||
stroke = ColorRGBa.BLUE
|
||||
lineStrip(bluePoints)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user