Tweak demos (#146)
This commit is contained in:
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,16 +20,33 @@ 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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
val histogram = calculateHistogramRGB(image, binCount = 8)
|
||||||
|
print("Histogram using ${histogram.binCount} bins per RGB channel")
|
||||||
|
|
||||||
|
val colorsSortedByFreq = histogram.sortedColors()
|
||||||
|
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 {
|
extend {
|
||||||
|
|
||||||
drawer.image(image)
|
drawer.image(image)
|
||||||
for (i in 0 until 32) {
|
drawer.stroke = null
|
||||||
drawer.fill = colors[i].first
|
var x = 0.0
|
||||||
drawer.stroke = null
|
topColorsSortedByLuminosity.forEachIndexed { i, (color, freq) ->
|
||||||
drawer.rectangle(i * (width/32.0), height-16.0, width/32.0, 16.0)
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user