Tweak demos (#146)

This commit is contained in:
Abe Pazos
2020-08-25 08:56:26 +02:00
committed by GitHub
parent 497c903800
commit 7004536dd4
5 changed files with 123 additions and 83 deletions

View File

@@ -1,27 +1,42 @@
import org.openrndr.application import org.openrndr.application
import org.openrndr.color.ColorRGBa import org.openrndr.color.ColorRGBa
import org.openrndr.draw.circleBatch import org.openrndr.draw.circleBatch
import org.openrndr.draw.shadeStyle
/* /*
This program demonstrates creating "pre-baked" batches of circles. Batches can have varying fill, stroke and This program demonstrates creating "pre-baked" batches of circles.
strokeWeight settings. Batches can have varying fill, stroke and strokeWeight settings.
Batches are (currently) static but stored in GPU memory. Batches are fast to draw. Batches are (currently) static but stored in GPU memory but can be
*/ animated using a vertex shader. Batches are fast to draw.
*/
fun main() = application { fun main() = application {
program { program {
val batch = drawer.circleBatch { val batch = drawer.circleBatch {
this.fill = ColorRGBa.PINK for (i in 0 until 2000) {
for (i in 0 until 100) { fill = ColorRGBa.PINK.shade(Math.random())
this.strokeWeight = Math.random() * 5.0 strokeWeight = Math.random() * 5
this.circle(Math.random() * width, Math.random() * height, 50.0 * Math.random() + 50.0 ) circle(width * 0.5, height * 0.5, 20 * Math.random() + 5)
} }
} }
extend { extend {
drawer.clear(ColorRGBa.GRAY) drawer.clear(ColorRGBa.GRAY)
// The following optional shadeStyle animates the batch
// by using polar coordinates:
// sets angle and radius based on time and shape ID.
drawer.shadeStyle = shadeStyle {
vertexTransform = """
float a = c_instance + p_time * 0.1;
float r = 200 + 100 * sin(a * 0.998);
x_position.x += r * sin(a);
x_position.y += r * cos(a);
""".trimIndent()
parameter("time", seconds)
}
drawer.circles(batch) drawer.circles(batch)
} }
} }

View File

@@ -1,12 +1,14 @@
// Create a simple rectangle composition based on colors sampled from image // Comparison of color lists generated by interpolating from
// PINK to BLUE in different color models
import org.openrndr.application import org.openrndr.application
import org.openrndr.color.ColorRGBa import org.openrndr.color.ColorRGBa
import org.openrndr.draw.isolated
import org.openrndr.extensions.SingleScreenshot import org.openrndr.extensions.SingleScreenshot
import org.openrndr.extras.color.palettes.rangeTo import org.openrndr.extras.color.palettes.rangeTo
import org.openrndr.extras.color.presets.CORAL
import org.openrndr.extras.color.spaces.toHSLUVa import org.openrndr.extras.color.spaces.toHSLUVa
import org.openrndr.math.Vector2
import org.openrndr.math.map
import org.openrndr.shape.Rectangle
fun main() = application { fun main() = application {
program { program {
@@ -16,60 +18,28 @@ fun main() = application {
this.outputFile = System.getProperty("screenshotPath") this.outputFile = System.getProperty("screenshotPath")
} }
} }
val numColors = 10
val colorLists = listOf(
ColorRGBa.PINK..ColorRGBa.BLUE.toHSVa() blend numColors,
ColorRGBa.PINK..ColorRGBa.BLUE blend numColors,
ColorRGBa.PINK..ColorRGBa.BLUE.toHSLUVa() blend numColors,
ColorRGBa.PINK..ColorRGBa.BLUE.toXSVa() blend numColors,
ColorRGBa.PINK..ColorRGBa.BLUE.toLUVa() blend numColors,
ColorRGBa.PINK..ColorRGBa.BLUE.toLCHUVa() blend numColors
)
extend { extend {
drawer.clear(ColorRGBa.WHITE)
drawer.isolated { drawer.stroke = null
for (c in ColorRGBa.PINK..ColorRGBa.BLUE.toHSVa() blend 10) { colorLists.forEachIndexed { listId, colorList ->
drawer.fill = c val x = map(0.0, 2.0,
drawer.rectangle(0.0, 0.0, 40.0, 40.0) width * 0.2, width * 0.8, listId % 3.0)
drawer.translate(0.0, 40.0) val y = map(0.0, 1.0,
} height * 0.3, height * 0.7, (listId / 3) * 1.0)
} colorList.forEachIndexed { colorId, color ->
drawer.translate(50.0, 0.0) drawer.fill = color
drawer.isolated { drawer.rectangle(
for (c in ColorRGBa.PINK..ColorRGBa.BLUE blend 10) { Rectangle.fromCenter(Vector2(x, y),
drawer.fill = c 180.0 - colorId * 150.0 / numColors))
drawer.rectangle(0.0, 0.0, 40.0, 40.0)
drawer.translate(0.0, 40.0)
}
}
drawer.translate(50.0, 0.0)
drawer.isolated {
for (c in ColorRGBa.PINK..ColorRGBa.BLUE.toHSLUVa() blend 10) {
drawer.fill = c.toSRGB()
drawer.rectangle(0.0, 0.0, 40.0, 40.0)
drawer.translate(0.0, 40.0)
}
}
drawer.translate(50.0, 0.0)
drawer.isolated {
for (c in ColorRGBa.PINK..ColorRGBa.BLUE.toXSVa() blend 10) {
drawer.fill = c.toSRGB()
drawer.rectangle(0.0, 0.0, 40.0, 40.0)
drawer.translate(0.0, 40.0)
}
}
drawer.translate(50.0, 0.0)
drawer.isolated {
for (c in ColorRGBa.PINK..ColorRGBa.BLUE.toLUVa() blend 10) {
drawer.fill = c.toSRGB()
drawer.rectangle(0.0, 0.0, 40.0, 40.0)
drawer.translate(0.0, 40.0)
}
}
drawer.translate(50.0, 0.0)
drawer.isolated {
for (c in ColorRGBa.PINK..ColorRGBa.BLUE.toLCHUVa() blend 10) {
drawer.fill = c.toSRGB()
drawer.rectangle(0.0, 0.0, 40.0, 40.0)
drawer.translate(0.0, 40.0)
} }
} }
} }

View File

@@ -1,9 +1,15 @@
// Draw rectangles shaded in RGB and HSLUV space // Draw rectangles shaded in RGB and HSLUV space
import org.openrndr.application import org.openrndr.application
import org.openrndr.color.ColorHSLa
import org.openrndr.color.ColorRGBa import org.openrndr.color.ColorRGBa
import org.openrndr.color.rgb
import org.openrndr.draw.isolated
import org.openrndr.draw.loadFont
import org.openrndr.extensions.SingleScreenshot import org.openrndr.extensions.SingleScreenshot
import org.openrndr.extras.color.spaces.toHSLUVa import org.openrndr.extras.color.spaces.ColorHSLUVa
import org.openrndr.math.Vector2
import org.openrndr.shape.Rectangle
fun main() { fun main() {
application { application {
@@ -14,17 +20,34 @@ fun main() {
this.outputFile = System.getProperty("screenshotPath") this.outputFile = System.getProperty("screenshotPath")
} }
} }
val font = loadFont("demo-data/fonts/IBMPlexMono-Regular.ttf", 26.0)
extend { extend {
val color = ColorRGBa.PINK
drawer.stroke = null drawer.stroke = null
for (i in 0 until 10) { drawer.clear(rgb(0.3))
drawer.fill = color.shade(1.0 - i / 10.0) val s = mouse.position.x / width
drawer.rectangle(100.0, 100.0 + i * 20.0, 100.0, 20.0) val l = mouse.position.y / height
for (a in 0 until 360 step 12) {
val pos = Vector2(0.0, 110.0)
drawer.isolated {
translate(bounds.center)
rotate(a * 1.0)
drawer.fill = color.toHSLUVa().shade(1.0 - i / 10.0).toRGBa().toSRGB() fill = ColorHSLUVa(a * 1.0, s, l).toRGBa().toSRGB()
drawer.rectangle(200.0, 100.0 + i * 20.0, 100.0, 20.0) rectangle(Rectangle(pos * 1.2, 40.0, 300.0))
fill = ColorHSLa(a * 1.0, s, l).toRGBa()
rectangle(Rectangle.fromCenter(pos, 30.0, 60.0))
} }
} }
drawer.fontMap = font
drawer.fill = if(l > 0.8) ColorRGBa.BLACK else ColorRGBa.WHITE
drawer.text("HSLa", width * 0.48, height * 0.73)
drawer.text("HSLUVa", width * 0.8, height * 0.52)
drawer.text("hue: 0 to 360, " +
"saturation: ${String.format("%.02f", s)}, " +
"lightness: ${String.format("%.02f", l)}",
30.0, 460.0)
}
} }
} }
} }

View File

@@ -13,18 +13,45 @@ fun main() = application {
this.outputFile = System.getProperty("screenshotPath") this.outputFile = System.getProperty("screenshotPath")
} }
} }
val useColors = 32
val image = loadImage("demo-data/images/image-001.png") val image = loadImage("demo-data/images/image-001.png")
val histogram = calculateHistogramRGB(image)
val colors = histogram.sortedColors()
extend {
drawer.image(image) val histogram = calculateHistogramRGB(image, binCount = 8)
for (i in 0 until 32) { print("Histogram using ${histogram.binCount} bins per RGB channel")
drawer.fill = colors[i].first
drawer.stroke = null val colorsSortedByFreq = histogram.sortedColors()
drawer.rectangle(i * (width/32.0), height-16.0, width/32.0, 16.0) println(" therefore it contains ${colorsSortedByFreq.size} colors.")
val topColors = colorsSortedByFreq.subList(0, useColors)
print("\nWe will use the most common $useColors")
val topColorsSortedByLuminosity = topColors.sortedBy {
it.first.toHSLa().l
} }
println(" and sort them by luminosity.")
val topColorsFreqSum = topColors.sumByDouble { it.second }
println("\nThose top $useColors colors represent " +
String.format("%.02f", 100 * topColorsFreqSum) +
"% of the image colors.")
extend {
drawer.image(image)
drawer.stroke = null
var x = 0.0
topColorsSortedByLuminosity.forEachIndexed { i, (color, freq) ->
drawer.fill = color
// draw horizontal bars
drawer.rectangle(x, 2.0, width.toDouble(), 16.0)
x += width * freq / topColorsFreqSum
// draw vertical bars
drawer.rectangle(i * width / useColors.toDouble() + 2.0,
height - 2.0,
width / useColors.toDouble() - 4.0,
-height * freq / topColorsFreqSum)
}
} }
} }
} }

View File

@@ -17,15 +17,20 @@ fun main() = application {
val image = loadImage("demo-data/images/image-001.png") val image = loadImage("demo-data/images/image-001.png")
// -- here we use non-uniform weighting, such that bright colors are prioritized // -- here we use non-uniform weighting, such that bright colors are prioritized
val histogram = calculateHistogramRGB(image, weighting = { val histogram = calculateHistogramRGB(image, weighting = {
((r+g+b)/3.0).pow(2.4) ((r + g + b) / 3.0).pow(2.4)
}) })
val colors = histogram.sortedColors() val colors = histogram.sortedColors()
// .subList(0, 32).sortedBy { it.first.toHSLa().h } // sort by hue
extend { extend {
drawer.image(image) drawer.image(image)
for (i in 0 until 32) { for (i in 0 until 32) {
drawer.fill = colors[i].first drawer.fill = colors[i].first
drawer.stroke = null drawer.stroke = null
drawer.rectangle(i * (width / 32.0), height - 16.0, width / 32.0, 16.0) drawer.rectangle(i * width / 32.0 + 2.0,
height - 2.0,
width / 32.0 - 4.0,
-16.0)
} }
} }
} }