Demos: ensure all use fun main() = application {
- Adjust some demo window sizes. - Replace Random.double by Double.uniform - Tweak some demos so screenshots look more interesting
This commit is contained in:
@@ -4,40 +4,38 @@ import org.openrndr.draw.isolated
|
||||
import org.openrndr.shape.Circle
|
||||
import org.openrndr.shape.Rectangle
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
|
||||
program {
|
||||
val cs = Rectangle(0.0, 0.0, 200.0, 200.0).contour
|
||||
val cc = Circle(100.0, 0.0, 100.0).contour
|
||||
program {
|
||||
val cs = Rectangle(0.0, 0.0, 200.0, 200.0).contour
|
||||
val cc = Circle(100.0, 0.0, 100.0).contour
|
||||
|
||||
extend {
|
||||
drawer.fill = ColorRGBa.GRAY
|
||||
drawer.stroke = ColorRGBa.PINK
|
||||
drawer.isolated {
|
||||
drawer.contour(cs)
|
||||
drawer.translate(300.0, 0.0)
|
||||
extend {
|
||||
drawer.fill = ColorRGBa.GRAY
|
||||
drawer.stroke = ColorRGBa.PINK
|
||||
drawer.isolated {
|
||||
drawer.contour(cs)
|
||||
drawer.translate(300.0, 0.0)
|
||||
|
||||
// this should create a contour similar to the input contour
|
||||
drawer.contour(cs.sampleEquidistant(4))
|
||||
drawer.contour(cs.sampleEquidistant(3))
|
||||
}
|
||||
// this should create a contour similar to the input contour
|
||||
drawer.contour(cs.sampleEquidistant(4))
|
||||
drawer.contour(cs.sampleEquidistant(3))
|
||||
}
|
||||
|
||||
drawer.isolated {
|
||||
drawer.translate(.0, 400.0)
|
||||
drawer.contour(cc)
|
||||
drawer.translate(300.0, 0.0)
|
||||
drawer.isolated {
|
||||
drawer.translate(.0, 400.0)
|
||||
drawer.contour(cc)
|
||||
drawer.translate(300.0, 0.0)
|
||||
|
||||
drawer.contour(cc)
|
||||
// this should draw a hexagon
|
||||
drawer.contour(cc.sampleEquidistant(6))
|
||||
// this should draw a triangle
|
||||
drawer.contour(cc.sampleEquidistant(3))
|
||||
}
|
||||
drawer.contour(cc)
|
||||
// this should draw a hexagon
|
||||
drawer.contour(cc.sampleEquidistant(6))
|
||||
// this should draw a triangle
|
||||
drawer.contour(cc.sampleEquidistant(3))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,38 +13,36 @@ import org.openrndr.shape.Triangle
|
||||
* a 3x3 grid of triangles and lines.
|
||||
*/
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
|
||||
program {
|
||||
val font = loadFont("demo-data/fonts/IBMPlexMono-Regular.ttf", 20.0)
|
||||
val pointA = Vector2(0.0, 50.0)
|
||||
val pointB = Vector2(50.0, -20.0)
|
||||
val pointC = Vector2(-50.0, 0.0)
|
||||
val triangle = Triangle(pointA, pointB, pointC).contour
|
||||
program {
|
||||
val font = loadFont("demo-data/fonts/IBMPlexMono-Regular.ttf", 20.0)
|
||||
val pointA = Vector2(0.0, 50.0)
|
||||
val pointB = Vector2(50.0, -20.0)
|
||||
val pointC = Vector2(-50.0, 0.0)
|
||||
val triangle = Triangle(pointA, pointB, pointC).contour
|
||||
|
||||
extend {
|
||||
drawer.apply {
|
||||
fill = ColorRGBa.GRAY
|
||||
stroke = ColorRGBa.PINK
|
||||
strokeWeight = 8.0
|
||||
fontMap = font
|
||||
LineCap.entries.forEachIndexed { x, cap ->
|
||||
lineCap = cap
|
||||
LineJoin.entries.forEachIndexed { y, join ->
|
||||
lineJoin = join
|
||||
val pos = IntVector2(x - 1, y - 1).vector2 * 180.0
|
||||
isolated {
|
||||
translate(bounds.position(0.46, 0.46) + pos)
|
||||
text("cap: ${cap.name}", -30.5, 80.5)
|
||||
text("join: ${join.name}", -30.5, 100.5)
|
||||
contour(triangle)
|
||||
lineSegment(pointA - pointC, pointB - pointC)
|
||||
}
|
||||
extend {
|
||||
drawer.apply {
|
||||
fill = ColorRGBa.GRAY
|
||||
stroke = ColorRGBa.PINK
|
||||
strokeWeight = 8.0
|
||||
fontMap = font
|
||||
LineCap.entries.forEachIndexed { x, cap ->
|
||||
lineCap = cap
|
||||
LineJoin.entries.forEachIndexed { y, join ->
|
||||
lineJoin = join
|
||||
val pos = IntVector2(x - 1, y - 1).vector2 * 180.0
|
||||
isolated {
|
||||
translate(bounds.position(0.46, 0.46) + pos)
|
||||
text("cap: ${cap.name}", -30.5, 80.5)
|
||||
text("join: ${join.name}", -30.5, 100.5)
|
||||
contour(triangle)
|
||||
lineSegment(pointA - pointC, pointB - pointC)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,41 +2,37 @@ import org.openrndr.application
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.composition.composition
|
||||
import org.openrndr.extra.composition.drawComposition
|
||||
import org.openrndr.extra.svg.saveToFile
|
||||
import org.openrndr.extra.svg.toSVG
|
||||
import org.openrndr.math.Vector2
|
||||
import java.io.File
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val composition = drawComposition {
|
||||
val layer = group {
|
||||
fill = ColorRGBa.PINK
|
||||
stroke = ColorRGBa.BLACK
|
||||
strokeWeight = 10.0
|
||||
circle(Vector2(width / 2.0, height / 2.0), 100.0)
|
||||
circle(Vector2(200.0, 200.0), 50.0)
|
||||
}
|
||||
// demonstrating how to set custom attributes on the CompositionNode
|
||||
// these are stored in SVG
|
||||
//layer.id = "Layer_2"
|
||||
//layer.attributes["inkscape:label"] = "Layer 1"
|
||||
//layer.attributes["inkscape:groupmode"] = "layer"
|
||||
fun main() = application {
|
||||
program {
|
||||
val composition = drawComposition {
|
||||
val layer = group {
|
||||
fill = ColorRGBa.PINK
|
||||
stroke = ColorRGBa.BLACK
|
||||
strokeWeight = 10.0
|
||||
circle(Vector2(width / 2.0, height / 2.0), 100.0)
|
||||
circle(Vector2(200.0, 200.0), 50.0)
|
||||
}
|
||||
// demonstrating how to set custom attributes on the CompositionNode
|
||||
// these are stored in SVG
|
||||
//layer.id = "Layer_2"
|
||||
//layer.attributes["inkscape:label"] = "Layer 1"
|
||||
//layer.attributes["inkscape:groupmode"] = "layer"
|
||||
}
|
||||
|
||||
// print the svg to the console
|
||||
println(composition.toSVG())
|
||||
// print the svg to the console
|
||||
println(composition.toSVG())
|
||||
|
||||
// save svg to a File
|
||||
//composition.saveToFile(File("/path/to/design.svg"))
|
||||
// save svg to a File
|
||||
//composition.saveToFile(File("/path/to/design.svg"))
|
||||
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.WHITE)
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.WHITE)
|
||||
|
||||
// draw the composition to the screen
|
||||
drawer.composition(composition)
|
||||
}
|
||||
// draw the composition to the screen
|
||||
drawer.composition(composition)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,23 +4,21 @@ import org.openrndr.extra.composition.ClipMode
|
||||
import org.openrndr.extra.composition.composition
|
||||
import org.openrndr.extra.composition.drawComposition
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val cd = drawComposition {
|
||||
fill = null
|
||||
circle(width / 2.0, height / 2.0, 100.0)
|
||||
fun main() = application {
|
||||
program {
|
||||
val cd = drawComposition {
|
||||
fill = null
|
||||
circle(width / 2.0, height / 2.0, 100.0)
|
||||
|
||||
fill = ColorRGBa.BLACK
|
||||
clipMode = ClipMode.REVERSE_DIFFERENCE
|
||||
circle(width / 2.0 + 50.0, height / 2.0, 100.0)
|
||||
}
|
||||
fill = ColorRGBa.BLACK
|
||||
clipMode = ClipMode.REVERSE_DIFFERENCE
|
||||
circle(width / 2.0 + 50.0, height / 2.0, 100.0)
|
||||
}
|
||||
|
||||
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
drawer.composition(cd)
|
||||
}
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
drawer.composition(cd)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,25 +4,22 @@ import org.openrndr.extra.composition.ClipMode
|
||||
import org.openrndr.extra.composition.composition
|
||||
import org.openrndr.extra.composition.drawComposition
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val cd = drawComposition {
|
||||
fill = null
|
||||
clipMode = ClipMode.REVERSE_DIFFERENCE
|
||||
fun main() = application {
|
||||
program {
|
||||
val cd = drawComposition {
|
||||
fill = null
|
||||
clipMode = ClipMode.REVERSE_DIFFERENCE
|
||||
|
||||
circle(width / 2.0-50.0, height / 2.0, 100.0)
|
||||
circle(width / 2.0+50.0, height / 2.0, 100.0)
|
||||
circle(width / 2.0 - 50.0, height / 2.0, 100.0)
|
||||
circle(width / 2.0 + 50.0, height / 2.0, 100.0)
|
||||
|
||||
fill = ColorRGBa.BLACK
|
||||
circle(width / 2.0, height / 2.0, 100.0)
|
||||
}
|
||||
fill = ColorRGBa.BLACK
|
||||
circle(width / 2.0, height / 2.0, 100.0)
|
||||
}
|
||||
|
||||
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
drawer.composition(cd)
|
||||
}
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
drawer.composition(cd)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -201,38 +201,36 @@ import org.openrndr.extra.fx.edges.EdgesWork
|
||||
import org.openrndr.extra.gui.GUI
|
||||
import org.openrndr.math.Vector2
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 768
|
||||
height = 768
|
||||
}
|
||||
program {
|
||||
val w2 = width / 2.0
|
||||
val h2 = height / 2.0
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 768
|
||||
height = 768
|
||||
}
|
||||
program {
|
||||
val w2 = width / 2.0
|
||||
val h2 = height / 2.0
|
||||
|
||||
val c = compose {
|
||||
draw {
|
||||
drawer.fill = ColorRGBa.PINK
|
||||
drawer.circle(width / 2.0, height / 2.0, 10.0)
|
||||
}
|
||||
|
||||
layer {
|
||||
blend(Add())
|
||||
|
||||
val c = compose {
|
||||
draw {
|
||||
drawer.fill = ColorRGBa.PINK
|
||||
drawer.circle(width / 2.0, height / 2.0, 10.0)
|
||||
drawer.circle(width / 2.0, height / 2.0, 100.0)
|
||||
}
|
||||
|
||||
layer {
|
||||
blend(Add())
|
||||
|
||||
draw {
|
||||
drawer.circle(width / 2.0, height / 2.0, 100.0)
|
||||
}
|
||||
post(ApproximateGaussianBlur()) {
|
||||
window = 10
|
||||
sigma = Math.cos(seconds * 10.0) * 10.0 + 10.0
|
||||
}
|
||||
post(ApproximateGaussianBlur()) {
|
||||
window = 10
|
||||
sigma = Math.cos(seconds * 10.0) * 10.0 + 10.0
|
||||
}
|
||||
}
|
||||
extend(gui)
|
||||
extend {
|
||||
c.draw(drawer)
|
||||
}
|
||||
}
|
||||
extend(gui)
|
||||
extend {
|
||||
c.draw(drawer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,29 +6,31 @@ import org.openrndr.extra.fx.blur.HashBlurDynamic
|
||||
import org.openrndr.extra.fx.patterns.Checkers
|
||||
import kotlin.math.cos
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val c = compose {
|
||||
layer {
|
||||
val a = aside(colorType = ColorType.FLOAT32) {
|
||||
post(Checkers()) {
|
||||
this.size = cos(seconds)*0.5 + 0.5
|
||||
}
|
||||
}
|
||||
draw {
|
||||
drawer.clear(ColorRGBa.GRAY.shade(0.5))
|
||||
drawer.circle(width/2.0, height/2.0, 100.0)
|
||||
}
|
||||
post(HashBlurDynamic(), a) {
|
||||
time = seconds
|
||||
radius = 25.0
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val c = compose {
|
||||
layer {
|
||||
val a = aside(colorType = ColorType.FLOAT32) {
|
||||
post(Checkers()) {
|
||||
this.size = cos(seconds + 2.0) * 0.5 + 0.5
|
||||
}
|
||||
}
|
||||
draw {
|
||||
drawer.clear(ColorRGBa.GRAY.shade(0.5))
|
||||
drawer.circle(width / 2.0, height / 2.0, 100.0)
|
||||
}
|
||||
post(HashBlurDynamic(), a) {
|
||||
time = seconds
|
||||
radius = 25.0
|
||||
}
|
||||
}
|
||||
extend {
|
||||
c.draw(drawer)
|
||||
}
|
||||
}
|
||||
extend {
|
||||
c.draw(drawer)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,8 +17,8 @@ import kotlin.random.Random
|
||||
*/
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 900
|
||||
height = 900
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
|
||||
program {
|
||||
|
||||
@@ -14,10 +14,9 @@ import org.openrndr.shape.Rectangle
|
||||
* Try changing which layer has multisampling applied and observe the results.
|
||||
*/
|
||||
fun main() = application {
|
||||
System.setProperty("org.openrndr.gl3.debug", "true")
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
|
||||
program {
|
||||
@@ -25,17 +24,17 @@ fun main() = application {
|
||||
layer(multisample = BufferMultisample.SampleCount(4)) {
|
||||
draw {
|
||||
drawer.translate(drawer.bounds.center)
|
||||
drawer.rotate(seconds)
|
||||
drawer.rotate(seconds + 5)
|
||||
drawer.fill = ColorRGBa.PINK
|
||||
drawer.rectangle(Rectangle.fromCenter(Vector2.ZERO, 200.0))
|
||||
}
|
||||
|
||||
layer {
|
||||
layer() {
|
||||
blend(Normal()) {
|
||||
clip = true
|
||||
}
|
||||
draw {
|
||||
drawer.rotate(seconds * -2)
|
||||
drawer.rotate((seconds + 5) * -2)
|
||||
drawer.fill = ColorRGBa.WHITE
|
||||
drawer.rectangle(Rectangle.fromCenter(Vector2.ZERO, 200.0))
|
||||
}
|
||||
|
||||
@@ -8,33 +8,31 @@ import org.openrndr.extra.gui.GUI
|
||||
import org.openrndr.extra.parameters.DoubleParameter
|
||||
import org.openrndr.math.Vector2
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val gui = GUI()
|
||||
fun main() = application {
|
||||
program {
|
||||
val gui = GUI()
|
||||
|
||||
val state = object {
|
||||
@DoubleParameter("radius", 0.0, 200.0)
|
||||
var radius = 100.0
|
||||
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()
|
||||
}
|
||||
val difference by differencing(::radius)
|
||||
val differenceHistory by tracking(::difference)
|
||||
val differenceMax by aggregating(::differenceHistory) {
|
||||
it.maxMag()
|
||||
}
|
||||
}
|
||||
|
||||
gui.add(state, "state")
|
||||
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))
|
||||
}
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,68 +12,66 @@ import org.openrndr.math.map
|
||||
* [grid] is used to layout graphs on rows and columns.
|
||||
*
|
||||
*/
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 1280
|
||||
height = 1080
|
||||
}
|
||||
program {
|
||||
val font = loadFont("demo-data/fonts/IBMPlexMono-Regular.ttf", 20.0)
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 1280
|
||||
height = 1080
|
||||
}
|
||||
program {
|
||||
val font = loadFont("demo-data/fonts/IBMPlexMono-Regular.ttf", 20.0)
|
||||
|
||||
// grid `columns * rows` must be >= Easing.values().size
|
||||
val grid = drawer.bounds.grid(
|
||||
3, 11, 10.0, 10.0, 10.0, 10.0
|
||||
).flatten()
|
||||
// grid `columns * rows` must be >= Easing.values().size
|
||||
val grid = drawer.bounds.grid(
|
||||
3, 11, 10.0, 10.0, 10.0, 10.0
|
||||
).flatten()
|
||||
|
||||
// make pairs of (easing function, grid rectangle)
|
||||
val pairs = Easing.values() zip grid
|
||||
// make pairs of (easing function, grid rectangle)
|
||||
val pairs = Easing.entries.toTypedArray() zip grid
|
||||
|
||||
extend {
|
||||
// ~4 seconds animation loop
|
||||
val animT = (frameCount % 240) / 60.0
|
||||
extend {
|
||||
// ~4 seconds animation loop
|
||||
val animT = (frameCount % 240) / 60.0
|
||||
|
||||
pairs.forEach { (easing, gridRect) ->
|
||||
pairs.forEach { (easing, gridRect) ->
|
||||
|
||||
// background rectangle
|
||||
drawer.stroke = null
|
||||
drawer.fill = ColorRGBa.WHITE.opacify(0.3)
|
||||
drawer.rectangle(gridRect)
|
||||
// background rectangle
|
||||
drawer.stroke = null
|
||||
drawer.fill = ColorRGBa.WHITE.opacify(0.3)
|
||||
drawer.rectangle(gridRect)
|
||||
|
||||
// graph
|
||||
drawer.stroke = ColorRGBa.PINK
|
||||
val points = List(40) {
|
||||
val curveT = it / 39.0
|
||||
gridRect.position(
|
||||
curveT, easing.function(curveT, 1.0, -1.0, 1.0)
|
||||
)
|
||||
}
|
||||
drawer.lineStrip(points)
|
||||
|
||||
// label
|
||||
drawer.fill = ColorRGBa.WHITE
|
||||
drawer.stroke = null
|
||||
drawer.fontMap = font
|
||||
drawer.text(
|
||||
easing.name,
|
||||
// text position rounded for crisp font rendering
|
||||
gridRect.position(0.02, 0.25).toInt().vector2
|
||||
// graph
|
||||
drawer.stroke = ColorRGBa.PINK
|
||||
val points = List(40) {
|
||||
val curveT = it / 39.0
|
||||
gridRect.position(
|
||||
curveT, easing.function(curveT, 1.0, -1.0, 1.0)
|
||||
)
|
||||
|
||||
// animation
|
||||
drawer.fill = ColorRGBa.WHITE.opacify(
|
||||
when { // 4-stage opacity
|
||||
animT > 3.0 -> 0.0 // invisible
|
||||
animT > 2.0 -> 3.0 - animT // fade-out
|
||||
animT < 1.0 -> animT // fade-in
|
||||
else -> 1.0 // visible
|
||||
}
|
||||
)
|
||||
// move only while visible (when loop time in 1.0..2.0)
|
||||
val t = animT.map(1.0, 2.0, 0.0, 1.0, true)
|
||||
val xy = Vector2(1.0, easing.function(t, 1.0, -1.0, 1.0))
|
||||
drawer.circle(gridRect.position(xy), 5.0)
|
||||
}
|
||||
drawer.lineStrip(points)
|
||||
|
||||
// label
|
||||
drawer.fill = ColorRGBa.WHITE
|
||||
drawer.stroke = null
|
||||
drawer.fontMap = font
|
||||
drawer.text(
|
||||
easing.name,
|
||||
// text position rounded for crisp font rendering
|
||||
gridRect.position(0.02, 0.25).toInt().vector2
|
||||
)
|
||||
|
||||
// animation
|
||||
drawer.fill = ColorRGBa.WHITE.opacify(
|
||||
when { // 4-stage opacity
|
||||
animT > 3.0 -> 0.0 // invisible
|
||||
animT > 2.0 -> 3.0 - animT // fade-out
|
||||
animT < 1.0 -> animT // fade-in
|
||||
else -> 1.0 // visible
|
||||
}
|
||||
)
|
||||
// move only while visible (when loop time in 1.0..2.0)
|
||||
val t = animT.map(1.0, 2.0, 0.0, 1.0, true)
|
||||
val xy = Vector2(1.0, easing.function(t, 1.0, -1.0, 1.0))
|
||||
drawer.circle(gridRect.position(xy), 5.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,34 +2,32 @@ import org.openrndr.application
|
||||
import org.openrndr.draw.loadFont
|
||||
import org.openrndr.extra.envelopes.ADSRTracker
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val tracker = ADSRTracker(this)
|
||||
tracker.attack = 1.0
|
||||
tracker.decay = 0.2
|
||||
tracker.sustain = 0.8
|
||||
tracker.release = 2.0
|
||||
fun main() = application {
|
||||
program {
|
||||
val tracker = ADSRTracker(this)
|
||||
tracker.attack = 1.0
|
||||
tracker.decay = 0.2
|
||||
tracker.sustain = 0.8
|
||||
tracker.release = 2.0
|
||||
|
||||
keyboard.keyDown.listen {
|
||||
if (it.name == "t")
|
||||
tracker.triggerOn()
|
||||
keyboard.keyDown.listen {
|
||||
if (it.name == "t")
|
||||
tracker.triggerOn()
|
||||
}
|
||||
keyboard.keyUp.listen {
|
||||
if (it.name == "t")
|
||||
tracker.triggerOff()
|
||||
}
|
||||
extend {
|
||||
tracker.values().forEach {
|
||||
drawer.circle(40.0, 40.0, 20.0 * it.value)
|
||||
drawer.translate(40.0, 0.0)
|
||||
}
|
||||
keyboard.keyUp.listen {
|
||||
if (it.name == "t")
|
||||
tracker.triggerOff()
|
||||
}
|
||||
extend {
|
||||
tracker.values().forEach {
|
||||
drawer.circle(40.0, 40.0, 20.0 * it.value)
|
||||
drawer.translate(40.0, 0.0)
|
||||
}
|
||||
drawer.defaults()
|
||||
drawer.circle(drawer.bounds.center, 100.0 * tracker.value())
|
||||
drawer.defaults()
|
||||
drawer.circle(drawer.bounds.center, 100.0 * tracker.value())
|
||||
|
||||
drawer.fontMap = loadFont("demo-data/fonts/IBMPlexMono-Regular.ttf", 16.0)
|
||||
drawer.text("press and hold 't'", 20.0, height - 20.0)
|
||||
}
|
||||
drawer.fontMap = loadFont("demo-data/fonts/IBMPlexMono-Regular.ttf", 16.0)
|
||||
drawer.text("press and hold 't'", 20.0, height - 20.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,43 +4,41 @@ import org.openrndr.extra.envelopes.ADSRTracker
|
||||
import org.openrndr.extra.noise.shapes.uniform
|
||||
import org.openrndr.shape.Rectangle
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val tracker = ADSRTracker(this)
|
||||
tracker.attack = 1.0
|
||||
tracker.decay = 0.2
|
||||
tracker.sustain = 0.8
|
||||
tracker.release = 2.0
|
||||
fun main() = application {
|
||||
program {
|
||||
val tracker = ADSRTracker(this)
|
||||
tracker.attack = 1.0
|
||||
tracker.decay = 0.2
|
||||
tracker.sustain = 0.8
|
||||
tracker.release = 2.0
|
||||
|
||||
keyboard.keyDown.listen {
|
||||
if (it.name == "t") {
|
||||
val center = drawer.bounds.offsetEdges(-30.0).uniform()
|
||||
tracker.triggerOn(0) { time, value, position ->
|
||||
drawer.circle(center, value * 100.0)
|
||||
}
|
||||
}
|
||||
if (it.name == "r") {
|
||||
val center = drawer.bounds.offsetEdges(-30.0).uniform()
|
||||
tracker.triggerOn(1) { time, value, position ->
|
||||
val r = Rectangle.fromCenter(center, width = value * 100.0, height = value * 100.0)
|
||||
drawer.rectangle(r)
|
||||
}
|
||||
keyboard.keyDown.listen {
|
||||
if (it.name == "t") {
|
||||
val center = drawer.bounds.offsetEdges(-30.0).uniform()
|
||||
tracker.triggerOn(0) { time, value, position ->
|
||||
drawer.circle(center, value * 100.0)
|
||||
}
|
||||
}
|
||||
keyboard.keyUp.listen {
|
||||
if (it.name == "t")
|
||||
tracker.triggerOff(0)
|
||||
if (it.name == "r")
|
||||
tracker.triggerOff(1)
|
||||
}
|
||||
extend {
|
||||
tracker.values().forEach {
|
||||
it()
|
||||
if (it.name == "r") {
|
||||
val center = drawer.bounds.offsetEdges(-30.0).uniform()
|
||||
tracker.triggerOn(1) { time, value, position ->
|
||||
val r = Rectangle.fromCenter(center, width = value * 100.0, height = value * 100.0)
|
||||
drawer.rectangle(r)
|
||||
}
|
||||
drawer.fontMap = loadFont("demo-data/fonts/IBMPlexMono-Regular.ttf", 16.0)
|
||||
drawer.text("press and hold 't' and/or 'r'", 20.0, height - 20.0)
|
||||
}
|
||||
}
|
||||
keyboard.keyUp.listen {
|
||||
if (it.name == "t")
|
||||
tracker.triggerOff(0)
|
||||
if (it.name == "r")
|
||||
tracker.triggerOff(1)
|
||||
}
|
||||
extend {
|
||||
tracker.values().forEach {
|
||||
it()
|
||||
}
|
||||
drawer.fontMap = loadFont("demo-data/fonts/IBMPlexMono-Regular.ttf", 16.0)
|
||||
drawer.text("press and hold 't' and/or 'r'", 20.0, height - 20.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,43 +4,41 @@ import org.openrndr.extra.gui.GUI
|
||||
import org.openrndr.extra.gui.addTo
|
||||
import org.openrndr.extra.parameters.TextParameter
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val gui = GUI()
|
||||
gui.compartmentsCollapsedByDefault = false
|
||||
fun main() = application {
|
||||
program {
|
||||
val gui = GUI()
|
||||
gui.compartmentsCollapsedByDefault = false
|
||||
|
||||
val settings = object {
|
||||
@TextParameter("x expression", order = 10)
|
||||
var xExpression = "cos(t) * 50.0 + width / 2.0"
|
||||
val settings = object {
|
||||
@TextParameter("x expression", order = 10)
|
||||
var xExpression = "cos(t) * 50.0 + width / 2.0"
|
||||
|
||||
@TextParameter("y expression", order = 20)
|
||||
var yExpression = "sin(t) * 50.0 + height / 2.0"
|
||||
@TextParameter("y expression", order = 20)
|
||||
var yExpression = "sin(t) * 50.0 + height / 2.0"
|
||||
|
||||
@TextParameter("radius expression", order = 30)
|
||||
var radiusExpression = "cos(t) * 50.0 + 50.0"
|
||||
}.addTo(gui)
|
||||
@TextParameter("radius expression", order = 30)
|
||||
var radiusExpression = "cos(t) * 50.0 + 50.0"
|
||||
}.addTo(gui)
|
||||
|
||||
extend(gui)
|
||||
extend {
|
||||
//gui.visible = mouse.position.x < 200.0
|
||||
extend(gui)
|
||||
extend {
|
||||
//gui.visible = mouse.position.x < 200.0
|
||||
|
||||
val expressionContext =
|
||||
mapOf("t" to seconds, "width" to drawer.bounds.width, "height" to drawer.bounds.height)
|
||||
val expressionContext =
|
||||
mapOf("t" to seconds, "width" to drawer.bounds.width, "height" to drawer.bounds.height)
|
||||
|
||||
fun eval(expression: String): Double =
|
||||
try {
|
||||
evaluateExpression(expression, expressionContext) ?: 0.0
|
||||
} catch (e: Throwable) {
|
||||
0.0
|
||||
}
|
||||
fun eval(expression: String): Double =
|
||||
try {
|
||||
evaluateExpression(expression, expressionContext) ?: 0.0
|
||||
} catch (e: Throwable) {
|
||||
0.0
|
||||
}
|
||||
|
||||
val x = eval(settings.xExpression)
|
||||
val y = eval(settings.yExpression)
|
||||
val radius = eval(settings.radiusExpression)
|
||||
val x = eval(settings.xExpression)
|
||||
val y = eval(settings.yExpression)
|
||||
val radius = eval(settings.radiusExpression)
|
||||
|
||||
drawer.circle(x, y, radius)
|
||||
}
|
||||
drawer.circle(x, y, radius)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,37 +8,35 @@ import org.openrndr.extra.parameters.TextParameter
|
||||
* Improved version of DemoExpressionEvaluator01, it uses [watchingExpression1] to automatically convert an expression
|
||||
* string into a function with a parameter "t".
|
||||
*/
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val gui = GUI()
|
||||
gui.compartmentsCollapsedByDefault = false
|
||||
fun main() = application {
|
||||
program {
|
||||
val gui = GUI()
|
||||
gui.compartmentsCollapsedByDefault = false
|
||||
|
||||
// the constants used in our expressions
|
||||
val constants = mutableMapOf("width" to drawer.width.toDouble(), "height" to drawer.height.toDouble())
|
||||
// the constants used in our expressions
|
||||
val constants = mutableMapOf("width" to drawer.width.toDouble(), "height" to drawer.height.toDouble())
|
||||
|
||||
val settings = object {
|
||||
@TextParameter("x expression", order = 10)
|
||||
var xExpression = "cos(t) * 50.0 + width / 2.0"
|
||||
val settings = object {
|
||||
@TextParameter("x expression", order = 10)
|
||||
var xExpression = "cos(t) * 50.0 + width / 2.0"
|
||||
|
||||
@TextParameter("y expression", order = 20)
|
||||
var yExpression = "sin(t) * 50.0 + height / 2.0"
|
||||
@TextParameter("y expression", order = 20)
|
||||
var yExpression = "sin(t) * 50.0 + height / 2.0"
|
||||
|
||||
@TextParameter("radius expression", order = 30)
|
||||
var radiusExpression = "cos(t) * 50.0 + 50.0"
|
||||
}.addTo(gui)
|
||||
@TextParameter("radius expression", order = 30)
|
||||
var radiusExpression = "cos(t) * 50.0 + 50.0"
|
||||
}.addTo(gui)
|
||||
|
||||
val xFunction by watchingExpression1(settings::xExpression, "t", constants)
|
||||
val yFunction by watchingExpression1(settings::yExpression, "t", constants)
|
||||
val radiusFunction by watchingExpression1(settings::radiusExpression, "t", constants)
|
||||
val xFunction by watchingExpression1(settings::xExpression, "t", constants)
|
||||
val yFunction by watchingExpression1(settings::yExpression, "t", constants)
|
||||
val radiusFunction by watchingExpression1(settings::radiusExpression, "t", constants)
|
||||
|
||||
extend(gui)
|
||||
extend {
|
||||
val x = xFunction(seconds)
|
||||
val y = yFunction(seconds)
|
||||
val radius = radiusFunction(seconds)
|
||||
drawer.circle(x, y, radius)
|
||||
}
|
||||
extend(gui)
|
||||
extend {
|
||||
val x = xFunction(seconds)
|
||||
val y = yFunction(seconds)
|
||||
val radius = radiusFunction(seconds)
|
||||
drawer.circle(x, y, radius)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -118,26 +118,25 @@ Drawing FCurves is useful for debugging, but their typical use is for animation.
|
||||
The FCurve sampler allows us to query values for the given time value like this:
|
||||
|
||||
```kotlin
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val xCurve = fcurve(
|
||||
"""
|
||||
M320 H0.4
|
||||
S2,0, 2,320
|
||||
S2,0, 2,320
|
||||
S2,0, 2,320
|
||||
S2,0, 2,320
|
||||
T0.6,320
|
||||
""".trimIndent()
|
||||
).sampler() // <--
|
||||
extend {
|
||||
drawer.circle(
|
||||
xCurve(seconds % 9.0),
|
||||
height * 0.5,
|
||||
20.0
|
||||
)
|
||||
}
|
||||
fun main() = application {
|
||||
program {
|
||||
val xCurve = fcurve(
|
||||
"""
|
||||
M320 H0.4
|
||||
S2,0, 2,320
|
||||
S2,0, 2,320
|
||||
S2,0, 2,320
|
||||
S2,0, 2,320
|
||||
T0.6,320
|
||||
"""
|
||||
)
|
||||
val xCurveSampler = xCurve.sampler()
|
||||
extend {
|
||||
drawer.circle(
|
||||
xCurveSampler(seconds % 9.0),
|
||||
240.0,
|
||||
20.0
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -194,6 +193,7 @@ For example `(M0 (h1 m1)[3])[2]` expands to `M0 h1 m1 h1 m1 h1 m1 M0 h1 m1 h1 m1
|
||||
|
||||
|
||||
# References
|
||||
|
||||
* https://x.com/ruby0x1/status/1258252352672247814
|
||||
* https://blender.stackexchange.com/questions/52403/what-is-the-mathematical-basis-for-f-curves/52468#52468
|
||||
* https://pomax.github.io/bezierinfo/#yforx
|
||||
@@ -210,6 +210,11 @@ For example `(M0 (h1 m1)[3])[2]` expands to `M0 h1 m1 h1 m1 h1 m1 M0 h1 m1 h1 m1
|
||||
|
||||

|
||||
|
||||
### DemoFCurve03
|
||||
[source code](src/jvmDemo/kotlin/DemoFCurve03.kt)
|
||||
|
||||

|
||||
|
||||
### DemoFCurveSheet01
|
||||
[source code](src/jvmDemo/kotlin/DemoFCurveSheet01.kt)
|
||||
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
import org.openrndr.application
|
||||
import org.openrndr.extra.fcurve.fcurve
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val xpos = fcurve("M0 Q4,360,5,720").sampler()
|
||||
val ypos = fcurve("M360 h5").sampler()
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val xpos = fcurve("M0 Q4,360,5,720").sampler()
|
||||
val ypos = fcurve("M360 h5").sampler()
|
||||
|
||||
extend {
|
||||
drawer.circle(xpos(seconds.mod(5.0)), ypos(seconds.mod(5.0)), 100.0)
|
||||
}
|
||||
extend {
|
||||
drawer.circle(xpos(seconds.mod(5.0)), ypos(seconds.mod(5.0)), 100.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,26 +3,24 @@ import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.fcurve.fcurve
|
||||
import org.openrndr.math.Vector2
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val xposCurve = fcurve("M0 Q4,360,5,720")
|
||||
val xpos = xposCurve.sampler()
|
||||
val yposCurve = fcurve("M360 h5")
|
||||
val ypos = yposCurve.sampler()
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val xposCurve = fcurve("M0 Q4,360,5,720")
|
||||
val xpos = xposCurve.sampler()
|
||||
val yposCurve = fcurve("M360 h5")
|
||||
val ypos = yposCurve.sampler()
|
||||
|
||||
extend {
|
||||
drawer.circle(xpos(seconds.mod(5.0)), ypos(seconds.mod(5.0)), 100.0)
|
||||
drawer.stroke = ColorRGBa.PINK
|
||||
drawer.contours(xposCurve.contours(Vector2(720.0 / 5.0, -1.0), Vector2(0.0, height * 1.0)))
|
||||
drawer.contours(yposCurve.contours(Vector2(720.0 / 5.0, -1.0), Vector2(0.0, height * 1.0)))
|
||||
drawer.translate(seconds.mod(5.0)*(720.0/5.0), 0.0)
|
||||
drawer.lineSegment(0.0, 0.0, 0.0, 720.0)
|
||||
}
|
||||
extend {
|
||||
drawer.circle(xpos(seconds.mod(5.0)), ypos(seconds.mod(5.0)), 100.0)
|
||||
drawer.stroke = ColorRGBa.PINK
|
||||
drawer.contours(xposCurve.contours(Vector2(720.0 / 5.0, -1.0), Vector2(0.0, height * 1.0)))
|
||||
drawer.contours(yposCurve.contours(Vector2(720.0 / 5.0, -1.0), Vector2(0.0, height * 1.0)))
|
||||
drawer.translate(seconds.mod(5.0) * (720.0 / 5.0), 0.0)
|
||||
drawer.lineSegment(0.0, 0.0, 0.0, 720.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,26 +3,26 @@ import org.openrndr.extra.fcurve.MultiFCurve
|
||||
import org.openrndr.extra.fcurve.fcurve
|
||||
import org.openrndr.extra.fcurve.vector2
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
class XYAnimation : MultiFCurve(mapOf(
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
class XYAnimation : MultiFCurve(
|
||||
mapOf(
|
||||
"x" to fcurve("M0 Q4,360,5,720"),
|
||||
"y" to fcurve("M360 h5")
|
||||
)) {
|
||||
val position = vector2("x", "y")
|
||||
}
|
||||
)
|
||||
) {
|
||||
val position = vector2("x", "y")
|
||||
}
|
||||
|
||||
val xyAnimation = XYAnimation()
|
||||
val position = xyAnimation.position.sampler()
|
||||
val xyAnimation = XYAnimation()
|
||||
val position = xyAnimation.position.sampler()
|
||||
|
||||
extend {
|
||||
drawer.circle(position(seconds.mod(5.0)), 100.0)
|
||||
}
|
||||
extend {
|
||||
drawer.circle(position(seconds.mod(5.0)), 100.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,148 +9,148 @@ import org.openrndr.math.Vector2
|
||||
import org.openrndr.math.smoothstep
|
||||
import org.openrndr.math.transforms.buildTransform
|
||||
import org.openrndr.shape.LineSegment
|
||||
import kotlin.math.*
|
||||
import kotlin.math.max
|
||||
import kotlin.random.Random
|
||||
|
||||
/**
|
||||
* Demonstration of using FFT to filter a two-dimensional shape. Mouse xy-position is mapped
|
||||
* to lowpass and highpass settings of the filter.
|
||||
*/
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val fftSize = 512
|
||||
val fft = FFT(fftSize)
|
||||
fun List<Vector2>.toFloatArrays(x: FloatArray, y: FloatArray) {
|
||||
for ((index, segment) in this.withIndex()) {
|
||||
x[index] = segment.x.toFloat()
|
||||
y[index] = segment.y.toFloat()
|
||||
}
|
||||
}
|
||||
program {
|
||||
val fftSize = 512
|
||||
val fft = FFT(fftSize)
|
||||
fun List<Vector2>.toFloatArrays(x: FloatArray, y: FloatArray) {
|
||||
for ((index, segment) in this.withIndex()) {
|
||||
x[index] = segment.x.toFloat()
|
||||
y[index] = segment.y.toFloat()
|
||||
}
|
||||
|
||||
fun vectorsFromFloatArrays(x: FloatArray, y: FloatArray): List<Vector2> {
|
||||
val n = x.size
|
||||
val result = mutableListOf<Vector2>()
|
||||
for (i in 0 until n) {
|
||||
result.add(Vector2(x[i].toDouble(), y[i].toDouble()))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun lp(t: Double, c: Double): Double {
|
||||
return smoothstep(c, c - 0.1, t)
|
||||
}
|
||||
|
||||
fun hp(t: Double, c: Double): Double {
|
||||
return smoothstep(c, c + 0.1, t)
|
||||
}
|
||||
|
||||
val c = hobbyCurve(
|
||||
drawer.bounds.scatter(30.0, distanceToEdge = 100.0, random = Random(3)).filter {
|
||||
Random.nextBoolean()
|
||||
},
|
||||
true
|
||||
).transform(buildTransform { translate(-drawer.bounds.center) })
|
||||
|
||||
val x = FloatArray(fftSize)
|
||||
val y = FloatArray(fftSize)
|
||||
|
||||
val xFiltered = FloatArray(fftSize)
|
||||
val yFiltered = FloatArray(fftSize)
|
||||
|
||||
extend {
|
||||
c.equidistantPositions(fftSize).toFloatArrays(x, y)
|
||||
|
||||
// process x-component
|
||||
fft.forward(x)
|
||||
|
||||
drawer.stroke = ColorRGBa.GRAY.shade(0.5)
|
||||
drawer.lineSegments((0 until fft.size / 2).map {
|
||||
LineSegment(
|
||||
it.toDouble() * 2.0 + 0.5,
|
||||
height * 0.5,
|
||||
it.toDouble() * 2.0 + 0.5,
|
||||
height * 0.5 - fft.magnitude(it) / 200.0,
|
||||
)
|
||||
})
|
||||
|
||||
|
||||
val xpower = fft.magnitudeSum()
|
||||
|
||||
val hpc = mouse.position.x / width
|
||||
val lpc = mouse.position.y / height
|
||||
|
||||
for (i in 1..fftSize / 2) {
|
||||
val t = i.toDouble() / (fftSize / 2 - 1)
|
||||
val f = if (hpc <= lpc) lp(t, lpc) * hp(t, hpc) else max(lp(t, lpc), hp(t, hpc))
|
||||
fft.scaleBand(i, f.toFloat())
|
||||
}
|
||||
val xfpower = fft.magnitudeSum().coerceAtLeast(1.0)
|
||||
|
||||
fft.scaleAll((xpower / xfpower).toFloat())
|
||||
drawer.stroke = ColorRGBa.PINK.opacify(0.8)
|
||||
drawer.lineSegments((0 until fft.size / 2).map {
|
||||
LineSegment(
|
||||
it.toDouble() * 2.0 + 0.5,
|
||||
height * 0.5,
|
||||
it.toDouble() * 2.0 + 0.5,
|
||||
height * 0.5 - fft.magnitude(it) / 200.0
|
||||
)
|
||||
})
|
||||
|
||||
fft.inverse(xFiltered)
|
||||
|
||||
// process y-component
|
||||
fft.forward(y)
|
||||
val ypower = fft.magnitudeSum()
|
||||
|
||||
drawer.stroke = ColorRGBa.GRAY.shade(0.5)
|
||||
drawer.lineSegments((0 until fft.size / 2).map {
|
||||
LineSegment(
|
||||
it * 2.0 + 0.5,
|
||||
height * 0.5,
|
||||
it * 2.0 + 0.5,
|
||||
height * 0.5 + fft.magnitude(it) / 200.0,
|
||||
)
|
||||
})
|
||||
|
||||
|
||||
for (i in 1..fftSize / 2) {
|
||||
val t = i.toDouble() / (fftSize / 2 - 1)
|
||||
val f = if (hpc <= lpc) lp(t, lpc) * hp(t, hpc) else max(lp(t, lpc), hp(t, hpc))
|
||||
fft.scaleBand(i, f.toFloat())
|
||||
}
|
||||
|
||||
fun vectorsFromFloatArrays(x: FloatArray, y: FloatArray): List<Vector2> {
|
||||
val n = x.size
|
||||
val result = mutableListOf<Vector2>()
|
||||
for (i in 0 until n) {
|
||||
result.add(Vector2(x[i].toDouble(), y[i].toDouble()))
|
||||
}
|
||||
return result
|
||||
}
|
||||
val yfpower = fft.magnitudeSum().coerceAtLeast(1.0)
|
||||
|
||||
fun lp(t: Double, c: Double): Double {
|
||||
return smoothstep(c, c - 0.1, t)
|
||||
}
|
||||
fft.scaleAll((ypower / yfpower).toFloat())
|
||||
drawer.stroke = ColorRGBa.PINK.opacify(0.7)
|
||||
drawer.lineSegments((0 until fft.size / 2).map {
|
||||
LineSegment(
|
||||
it * 2.0 + 0.5,
|
||||
height * 0.5,
|
||||
it * 2.0 + 0.5,
|
||||
height * 0.5 + fft.magnitude(it) / 200.0,
|
||||
)
|
||||
})
|
||||
fft.inverse(yFiltered)
|
||||
|
||||
fun hp(t: Double, c: Double): Double {
|
||||
return smoothstep(c, c + 0.1, t)
|
||||
}
|
||||
val cr = vectorsFromFloatArrays(xFiltered, yFiltered).catmullRom(closed = true).toContour()
|
||||
//val cr = ShapeContour.fromPoints(vectorsFromFloatArrays(xr, yr), closed=true)
|
||||
|
||||
val c = hobbyCurve(
|
||||
drawer.bounds.scatter(40.0, distanceToEdge = 100.0, random = Random(0)),
|
||||
true
|
||||
).transform(buildTransform { translate(-drawer.bounds.center) })
|
||||
val recenteredShape = cr.transform(buildTransform {
|
||||
translate(drawer.bounds.center)
|
||||
})
|
||||
drawer.fill = null
|
||||
drawer.stroke = ColorRGBa.WHITE
|
||||
|
||||
val x = FloatArray(fftSize)
|
||||
val y = FloatArray(fftSize)
|
||||
drawer.lineSegment(mouse.position.x / width * 512, 0.0, mouse.position.x / width * 512, height * 1.0)
|
||||
drawer.lineSegment(mouse.position.y / height * 512, 0.0, mouse.position.y / height * 512, height * 1.0)
|
||||
|
||||
val xFiltered = FloatArray(fftSize)
|
||||
val yFiltered = FloatArray(fftSize)
|
||||
|
||||
extend {
|
||||
c.equidistantPositions(fftSize).toFloatArrays(x, y)
|
||||
|
||||
// process x-component
|
||||
fft.forward(x)
|
||||
|
||||
drawer.stroke = ColorRGBa.GRAY.shade(0.5)
|
||||
drawer.lineSegments((0 until fft.size / 2).map {
|
||||
LineSegment(
|
||||
it.toDouble() * 2.0 + 0.5,
|
||||
height * 0.5,
|
||||
it.toDouble() * 2.0 + 0.5,
|
||||
height * 0.5 - fft.magnitude(it) / 200.0,
|
||||
)
|
||||
})
|
||||
|
||||
|
||||
val xpower = fft.magnitudeSum()
|
||||
|
||||
val lpc = mouse.position.x / width
|
||||
val hpc = mouse.position.y / height
|
||||
|
||||
for (i in 1..fftSize / 2) {
|
||||
val t = i.toDouble() / (fftSize / 2 - 1)
|
||||
val f = if (hpc <= lpc) lp(t, lpc) * hp(t, hpc) else max(lp(t, lpc), hp(t, hpc))
|
||||
fft.scaleBand(i, f.toFloat())
|
||||
}
|
||||
val xfpower = fft.magnitudeSum().coerceAtLeast(1.0)
|
||||
|
||||
fft.scaleAll((xpower / xfpower).toFloat())
|
||||
drawer.stroke = ColorRGBa.PINK.opacify(0.8)
|
||||
drawer.lineSegments((0 until fft.size / 2).map {
|
||||
LineSegment(
|
||||
it.toDouble() * 2.0 + 0.5,
|
||||
height * 0.5,
|
||||
it.toDouble() * 2.0 + 0.5,
|
||||
height * 0.5 - fft.magnitude(it) / 200.0
|
||||
)
|
||||
})
|
||||
|
||||
fft.inverse(xFiltered)
|
||||
|
||||
// process y-component
|
||||
fft.forward(y)
|
||||
val ypower = fft.magnitudeSum()
|
||||
|
||||
drawer.stroke = ColorRGBa.GRAY.shade(0.5)
|
||||
drawer.lineSegments((0 until fft.size / 2).map {
|
||||
LineSegment(
|
||||
it.toDouble() * 2.0 + 0.5,
|
||||
height * 0.5,
|
||||
it.toDouble() * 2.0 + 0.5,
|
||||
height * 0.5 + fft.magnitude(it) / 200.0,
|
||||
)
|
||||
})
|
||||
|
||||
|
||||
for (i in 1..fftSize / 2) {
|
||||
val t = i.toDouble() / (fftSize / 2 - 1)
|
||||
val f = if (hpc <= lpc) lp(t, lpc) * hp(t, hpc) else max(lp(t, lpc), hp(t, hpc))
|
||||
fft.scaleBand(i, f.toFloat())
|
||||
}
|
||||
|
||||
val yfpower = fft.magnitudeSum().coerceAtLeast(1.0)
|
||||
|
||||
fft.scaleAll((ypower / yfpower).toFloat())
|
||||
drawer.stroke = ColorRGBa.PINK.opacify(0.7)
|
||||
drawer.lineSegments((0 until fft.size / 2).map {
|
||||
LineSegment(
|
||||
it.toDouble() * 2.0 + 0.5,
|
||||
height * 0.5,
|
||||
it.toDouble() * 2.0 + 0.5,
|
||||
height * 0.5 + fft.magnitude(it) / 200.0,
|
||||
)
|
||||
})
|
||||
fft.inverse(yFiltered)
|
||||
|
||||
val cr = vectorsFromFloatArrays(xFiltered, yFiltered).catmullRom(closed = true).toContour()
|
||||
//val cr = ShapeContour.fromPoints(vectorsFromFloatArrays(xr, yr), closed=true)
|
||||
|
||||
val recenteredShape = cr.transform(buildTransform {
|
||||
translate(drawer.bounds.center)
|
||||
})
|
||||
drawer.fill = null
|
||||
drawer.stroke = ColorRGBa.WHITE
|
||||
|
||||
drawer.lineSegment(mouse.position.x / width * 512, 0.0, mouse.position.x / width * 512, height * 1.0)
|
||||
drawer.lineSegment(mouse.position.y / height * 512, 0.0, mouse.position.y / height * 512, height * 1.0)
|
||||
|
||||
drawer.contour(recenteredShape)
|
||||
}
|
||||
drawer.contour(recenteredShape)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,29 +1,28 @@
|
||||
import org.openrndr.application
|
||||
import org.openrndr.extra.fx.blend.*
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val add = Add()
|
||||
val colorBurn = ColorBurn()
|
||||
val colorDodge = ColorDodge()
|
||||
val darken = Darken()
|
||||
val destIn = DestinationIn()
|
||||
val destOut = DestinationOut()
|
||||
val destAtop = DestinationAtop()
|
||||
val hardLight = HardLight()
|
||||
val lighten = Lighten()
|
||||
val multiply = Multiply()
|
||||
val multiplyContrast = MultiplyContrast()
|
||||
val normal = Normal()
|
||||
val overlay = Overlay()
|
||||
val passthrough = Passthrough()
|
||||
val screen = Screen()
|
||||
val sourceIn = SourceIn()
|
||||
val sourceAtop = SourceAtop()
|
||||
val sourceOut = SourceOut()
|
||||
val subtract = Subtract()
|
||||
val xor = Xor()
|
||||
application.exit()
|
||||
}
|
||||
|
||||
fun main() = application {
|
||||
program {
|
||||
val add = Add()
|
||||
val colorBurn = ColorBurn()
|
||||
val colorDodge = ColorDodge()
|
||||
val darken = Darken()
|
||||
val destIn = DestinationIn()
|
||||
val destOut = DestinationOut()
|
||||
val destAtop = DestinationAtop()
|
||||
val hardLight = HardLight()
|
||||
val lighten = Lighten()
|
||||
val multiply = Multiply()
|
||||
val multiplyContrast = MultiplyContrast()
|
||||
val normal = Normal()
|
||||
val overlay = Overlay()
|
||||
val passthrough = Passthrough()
|
||||
val screen = Screen()
|
||||
val sourceIn = SourceIn()
|
||||
val sourceAtop = SourceAtop()
|
||||
val sourceOut = SourceOut()
|
||||
val subtract = Subtract()
|
||||
val xor = Xor()
|
||||
application.exit()
|
||||
}
|
||||
}
|
||||
@@ -5,104 +5,115 @@ import org.openrndr.extra.fx.blur.*
|
||||
import org.openrndr.math.Polar
|
||||
import kotlin.math.sin
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
// In this buffer we will draw some simple shapes
|
||||
val dry = renderTarget(width / 3, height / 3) {
|
||||
colorBuffer()
|
||||
fun main() = application {
|
||||
program {
|
||||
// In this buffer we will draw some simple shapes
|
||||
val dry = renderTarget(width / 3, height / 3) {
|
||||
colorBuffer()
|
||||
}
|
||||
|
||||
// The list of effects to demo
|
||||
val effects = listOf(
|
||||
BoxBlur(),
|
||||
ApproximateGaussianBlur(),
|
||||
HashBlur(),
|
||||
GaussianBlur(),
|
||||
GaussianBloom(),
|
||||
FrameBlur(),
|
||||
ZoomBlur(),
|
||||
LaserBlur()
|
||||
)
|
||||
|
||||
// On this buffer we will draw the dry buffer with an effect applied
|
||||
val wet = colorBuffer(dry.width, dry.height)
|
||||
|
||||
val font = loadFont("demo-data/fonts/IBMPlexMono-Regular.ttf", 16.0)
|
||||
|
||||
extend {
|
||||
// Draw two moving circles
|
||||
drawer.isolatedWithTarget(dry) {
|
||||
clear(ColorRGBa.BLACK)
|
||||
|
||||
fill = null
|
||||
stroke = ColorRGBa.PINK
|
||||
strokeWeight = 25.0
|
||||
circle(
|
||||
bounds.center +
|
||||
Polar(seconds * 50.0, 100.0).cartesian,
|
||||
200.0 + 50.0 * sin(seconds * 2.0)
|
||||
)
|
||||
|
||||
fill = ColorRGBa.PINK
|
||||
stroke = null
|
||||
circle(
|
||||
bounds.center +
|
||||
Polar(seconds * 50.0 + 60, 100.0).cartesian,
|
||||
100.0 + 20.0 * sin(seconds * 2.0 + 1)
|
||||
)
|
||||
}
|
||||
|
||||
// The list of effects to demo
|
||||
val effects = listOf(
|
||||
BoxBlur(),
|
||||
ApproximateGaussianBlur(),
|
||||
HashBlur(),
|
||||
GaussianBlur(),
|
||||
GaussianBloom(),
|
||||
FrameBlur(),
|
||||
ZoomBlur(),
|
||||
LaserBlur()
|
||||
)
|
||||
effects.forEachIndexed { i, blur ->
|
||||
// Adjust the effect settings.
|
||||
// All the values could be animated.
|
||||
when (blur) {
|
||||
is BoxBlur -> {
|
||||
blur.window = 30
|
||||
}
|
||||
|
||||
// On this buffer we will draw the dry buffer with an effect applied
|
||||
val wet = colorBuffer(dry.width, dry.height)
|
||||
is ApproximateGaussianBlur -> {
|
||||
blur.window = 25
|
||||
blur.sigma = 15.0
|
||||
}
|
||||
|
||||
val font = loadFont("demo-data/fonts/IBMPlexMono-Regular.ttf", 16.0)
|
||||
is HashBlur -> {
|
||||
blur.samples = 50
|
||||
blur.radius = 5.0
|
||||
blur.time = seconds
|
||||
}
|
||||
|
||||
extend {
|
||||
// Draw two moving circles
|
||||
drawer.isolatedWithTarget(dry) {
|
||||
clear(ColorRGBa.BLACK)
|
||||
is GaussianBlur -> {
|
||||
blur.window = 25
|
||||
blur.sigma = 15.0
|
||||
}
|
||||
|
||||
fill = null
|
||||
stroke = ColorRGBa.PINK
|
||||
strokeWeight = 25.0
|
||||
circle(bounds.center +
|
||||
Polar(seconds * 50.0, 100.0).cartesian,
|
||||
200.0 + 50.0 * sin(seconds * 2.0))
|
||||
is GaussianBloom -> {
|
||||
blur.window = 5
|
||||
blur.sigma = 3.0
|
||||
blur.gain = 3.0
|
||||
blur.noiseSeed = seconds
|
||||
}
|
||||
|
||||
fill = ColorRGBa.PINK
|
||||
stroke = null
|
||||
circle(bounds.center +
|
||||
Polar(seconds * 50.0 + 60, 100.0).cartesian,
|
||||
100.0 + 20.0 * sin(seconds * 2.0 + 1))
|
||||
is FrameBlur -> {
|
||||
blur.blend = 0.05
|
||||
}
|
||||
|
||||
is ZoomBlur -> {
|
||||
blur.center = Polar(seconds * 77.0, 0.5)
|
||||
.cartesian
|
||||
blur.strength = 0.8
|
||||
}
|
||||
|
||||
is LaserBlur -> {
|
||||
blur.center = Polar(seconds * 77.0, 0.5)
|
||||
.cartesian
|
||||
blur.aberration = 0.03
|
||||
blur.radius = 0.5
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
effects.forEachIndexed { i, blur ->
|
||||
// Adjust the effect settings.
|
||||
// All the values could be animated.
|
||||
when (blur) {
|
||||
is BoxBlur -> {
|
||||
blur.window = 30
|
||||
}
|
||||
is ApproximateGaussianBlur -> {
|
||||
blur.window = 25
|
||||
blur.sigma = 15.0
|
||||
}
|
||||
is HashBlur -> {
|
||||
blur.samples = 50
|
||||
blur.radius = 5.0
|
||||
blur.time = seconds
|
||||
}
|
||||
is GaussianBlur -> {
|
||||
blur.window = 25
|
||||
blur.sigma = 15.0
|
||||
}
|
||||
is GaussianBloom -> {
|
||||
blur.window = 5
|
||||
blur.sigma = 3.0
|
||||
blur.gain = 3.0
|
||||
blur.noiseSeed = seconds
|
||||
}
|
||||
is FrameBlur -> {
|
||||
blur.blend = 0.05
|
||||
}
|
||||
is ZoomBlur -> {
|
||||
blur.center = Polar(seconds * 77.0, 0.5)
|
||||
.cartesian
|
||||
blur.strength = 0.8
|
||||
}
|
||||
is LaserBlur -> {
|
||||
blur.center = Polar(seconds * 77.0, 0.5)
|
||||
.cartesian
|
||||
blur.aberration = 0.03
|
||||
blur.radius = 0.5
|
||||
// Apply the effect on `dry` writing the result to `wet`
|
||||
blur.apply(dry.colorBuffer(0), wet)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Apply the effect on `dry` writing the result to `wet`
|
||||
blur.apply(dry.colorBuffer(0), wet)
|
||||
|
||||
// Draw `wet` and write the effect name on top
|
||||
drawer.isolated {
|
||||
translate((i % 3) * width / 3.0,
|
||||
(i / 3) * height / 3.0)
|
||||
image(wet)
|
||||
fontMap = font
|
||||
text(blur.javaClass.simpleName, 20.0, 30.0)
|
||||
}
|
||||
// Draw `wet` and write the effect name on top
|
||||
drawer.isolated {
|
||||
translate(
|
||||
(i % 3) * width / 3.0,
|
||||
(i / 3) * height / 3.0
|
||||
)
|
||||
image(wet)
|
||||
fontMap = font
|
||||
text(blur.javaClass.simpleName, 20.0, 30.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,19 +3,17 @@ import org.openrndr.draw.createEquivalent
|
||||
import org.openrndr.draw.loadImage
|
||||
import org.openrndr.extra.fx.color.Duotone
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
fun main() = application {
|
||||
program {
|
||||
|
||||
val image = loadImage("demo-data/images/image-001.png")
|
||||
val filteredImage = image.createEquivalent()
|
||||
val duotone = Duotone()
|
||||
val image = loadImage("demo-data/images/image-001.png")
|
||||
val filteredImage = image.createEquivalent()
|
||||
val duotone = Duotone()
|
||||
|
||||
extend {
|
||||
duotone.labInterpolation = seconds.mod(2.0) < 1.0
|
||||
duotone.apply(image, filteredImage)
|
||||
drawer.image(filteredImage)
|
||||
}
|
||||
extend {
|
||||
duotone.labInterpolation = seconds.mod(2.0) < 1.0
|
||||
duotone.apply(image, filteredImage)
|
||||
drawer.image(filteredImage)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,18 +3,16 @@ import org.openrndr.draw.createEquivalent
|
||||
import org.openrndr.draw.loadImage
|
||||
import org.openrndr.extra.fx.color.Posterize
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val image = loadImage("demo-data/images/image-001.png")
|
||||
val filteredImage = image.createEquivalent()
|
||||
val posterize = Posterize()
|
||||
fun main() = application {
|
||||
program {
|
||||
val image = loadImage("demo-data/images/image-001.png")
|
||||
val filteredImage = image.createEquivalent()
|
||||
val posterize = Posterize()
|
||||
|
||||
extend {
|
||||
posterize.levels = 2
|
||||
posterize.apply(image, filteredImage)
|
||||
drawer.image(filteredImage)
|
||||
}
|
||||
extend {
|
||||
posterize.levels = 2
|
||||
posterize.apply(image, filteredImage)
|
||||
drawer.image(filteredImage)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,17 +5,15 @@ import org.openrndr.draw.loadImage
|
||||
import org.openrndr.extra.fx.colormap.GrayscaleColormap
|
||||
import kotlin.math.sin
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val colormap = GrayscaleColormap()
|
||||
val image = loadImage("demo-data/images/image-001.png")
|
||||
val colormapImage = image.createEquivalent(type = ColorType.FLOAT32)
|
||||
extend {
|
||||
colormap.curve = 1.0 + sin(seconds) * .5
|
||||
colormap.apply(image, colormapImage)
|
||||
drawer.image(colormapImage)
|
||||
}
|
||||
fun main() = application {
|
||||
program {
|
||||
val colormap = GrayscaleColormap()
|
||||
val image = loadImage("demo-data/images/image-001.png")
|
||||
val colormapImage = image.createEquivalent(type = ColorType.FLOAT32)
|
||||
extend {
|
||||
colormap.curve = 1.0 + sin(seconds) * .5
|
||||
colormap.apply(image, colormapImage)
|
||||
drawer.image(colormapImage)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,17 +5,15 @@ import org.openrndr.draw.loadImage
|
||||
import org.openrndr.extra.fx.colormap.SpectralZucconiColormap
|
||||
import kotlin.math.sin
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val colormap = SpectralZucconiColormap()
|
||||
val image = loadImage("demo-data/images/image-001.png")
|
||||
val colormapImage = image.createEquivalent(type = ColorType.FLOAT32)
|
||||
extend {
|
||||
colormap.curve = 1.0 + sin(seconds) * .5
|
||||
colormap.apply(image, colormapImage)
|
||||
drawer.image(colormapImage)
|
||||
}
|
||||
fun main() = application {
|
||||
program {
|
||||
val colormap = SpectralZucconiColormap()
|
||||
val image = loadImage("demo-data/images/image-001.png")
|
||||
val colormapImage = image.createEquivalent(type = ColorType.FLOAT32)
|
||||
extend {
|
||||
colormap.curve = 1.0 + sin(seconds) * .5
|
||||
colormap.apply(image, colormapImage)
|
||||
drawer.image(colormapImage)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,17 +5,15 @@ import org.openrndr.draw.loadImage
|
||||
import org.openrndr.extra.fx.colormap.TurboColormap
|
||||
import kotlin.math.sin
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val colormap = TurboColormap()
|
||||
val image = loadImage("demo-data/images/image-001.png")
|
||||
val colormapImage = image.createEquivalent(type = ColorType.FLOAT32)
|
||||
extend {
|
||||
colormap.curve = 1.0 + sin(seconds) * .5
|
||||
colormap.apply(image, colormapImage)
|
||||
drawer.image(colormapImage)
|
||||
}
|
||||
fun main() = application {
|
||||
program {
|
||||
val colormap = TurboColormap()
|
||||
val image = loadImage("demo-data/images/image-001.png")
|
||||
val colormapImage = image.createEquivalent(type = ColorType.FLOAT32)
|
||||
extend {
|
||||
colormap.curve = 1.0 + sin(seconds) * .5
|
||||
colormap.apply(image, colormapImage)
|
||||
drawer.image(colormapImage)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,53 +11,55 @@ import org.openrndr.extra.noise.*
|
||||
import org.openrndr.math.smoothstep
|
||||
import kotlin.math.cos
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
extend(Post()) {
|
||||
// -- create a color buffer and fill it with random direction vectors
|
||||
val direction = colorBuffer(width, height, type = ColorType.FLOAT32)
|
||||
val s = direction.shadow
|
||||
val n = simplex2D.bipolar().fbm().scaleShiftInput(0.01, 0.0, 0.01, 0.0).withVector2Output()
|
||||
val ng = simplex2D.unipolar().scaleShiftInput(0.005, 0.0, 0.005, 0.0)
|
||||
for (y in 0 until height) {
|
||||
for (x in 0 until width) {
|
||||
val a = smoothstep(0.4, 0.6, cos((x + y) * 0.01) * 0.5 + 0.5)
|
||||
val nv = n(2320, x.toDouble(), y.toDouble()) * smoothstep(0.45, 0.55, ng(1032, x.toDouble(), y.toDouble()))
|
||||
s[x, y] = ColorRGBa(nv.x, nv.y, 0.0, 1.0)
|
||||
}
|
||||
fun main() = application {
|
||||
program {
|
||||
extend(Post()) {
|
||||
// -- create a color buffer and fill it with random direction vectors
|
||||
val direction = colorBuffer(width, height, type = ColorType.FLOAT32)
|
||||
val s = direction.shadow
|
||||
val n = simplex2D.bipolar().fbm().scaleShiftInput(0.01, 0.0, 0.01, 0.0).withVector2Output()
|
||||
val ng = simplex2D.unipolar().scaleShiftInput(0.005, 0.0, 0.005, 0.0)
|
||||
for (y in 0 until height) {
|
||||
for (x in 0 until width) {
|
||||
val a = smoothstep(0.4, 0.6, cos((x + y) * 0.01) * 0.5 + 0.5)
|
||||
val nv = n(2320, x.toDouble(), y.toDouble()) * smoothstep(
|
||||
0.45,
|
||||
0.55,
|
||||
ng(1032, x.toDouble(), y.toDouble())
|
||||
)
|
||||
s[x, y] = ColorRGBa(nv.x, nv.y, 0.0, 1.0)
|
||||
}
|
||||
s.upload()
|
||||
}
|
||||
s.upload()
|
||||
|
||||
val directional = DirectionalBlur()
|
||||
val directional = DirectionalBlur()
|
||||
|
||||
// -- create a bidirectional composite filter by using a directional filter twice
|
||||
val bidirectional = directional.then(directional) {
|
||||
firstParameters {
|
||||
window = 50
|
||||
perpendicular = false
|
||||
}
|
||||
secondParameters {
|
||||
window = 3
|
||||
perpendicular = true
|
||||
}
|
||||
// -- create a bidirectional composite filter by using a directional filter twice
|
||||
val bidirectional = directional.then(directional) {
|
||||
firstParameters {
|
||||
window = 50
|
||||
perpendicular = false
|
||||
}
|
||||
|
||||
val grain = FilmGrain()
|
||||
grain.grainStrength = 1.0
|
||||
|
||||
// -- create a grain-blur composite filter
|
||||
val grainBlur = grain.then(bidirectional)
|
||||
|
||||
post { input, output ->
|
||||
grainBlur.apply(arrayOf(input, direction), output)
|
||||
secondParameters {
|
||||
window = 3
|
||||
perpendicular = true
|
||||
}
|
||||
}
|
||||
|
||||
val image = loadImage("demo-data/images/image-001.png")
|
||||
extend {
|
||||
drawer.image(image)
|
||||
val grain = FilmGrain()
|
||||
grain.grainStrength = 1.0
|
||||
|
||||
// -- create a grain-blur composite filter
|
||||
val grainBlur = grain.then(bidirectional)
|
||||
|
||||
post { input, output ->
|
||||
grainBlur.apply(arrayOf(input, direction), output)
|
||||
}
|
||||
}
|
||||
|
||||
val image = loadImage("demo-data/images/image-001.png")
|
||||
extend {
|
||||
drawer.image(image)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,23 +3,21 @@ import org.openrndr.draw.createEquivalent
|
||||
import org.openrndr.draw.loadImage
|
||||
import org.openrndr.extra.fx.dither.LumaHalftone
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val image = loadImage("demo-data/images/image-001.png")
|
||||
val filteredImage = image.createEquivalent()
|
||||
val lumaHalftone = LumaHalftone()
|
||||
extend {
|
||||
lumaHalftone.rotation = -15.0
|
||||
lumaHalftone.freq0 = 100.0
|
||||
lumaHalftone.gain1 = 1.0
|
||||
lumaHalftone.threshold = 0.5
|
||||
lumaHalftone.phase0 = seconds*0.1
|
||||
lumaHalftone.phase1 = -seconds*0.1
|
||||
lumaHalftone.apply(image, filteredImage)
|
||||
lumaHalftone.invert = seconds.mod(2.0) < 1.0
|
||||
drawer.image(filteredImage)
|
||||
}
|
||||
fun main() = application {
|
||||
program {
|
||||
val image = loadImage("demo-data/images/image-001.png")
|
||||
val filteredImage = image.createEquivalent()
|
||||
val lumaHalftone = LumaHalftone()
|
||||
extend {
|
||||
lumaHalftone.rotation = -15.0
|
||||
lumaHalftone.freq0 = 100.0
|
||||
lumaHalftone.gain1 = 1.0
|
||||
lumaHalftone.threshold = 0.5
|
||||
lumaHalftone.phase0 = seconds * 0.1
|
||||
lumaHalftone.phase1 = -seconds * 0.1
|
||||
lumaHalftone.apply(image, filteredImage)
|
||||
lumaHalftone.invert = seconds.mod(2.0) < 1.0
|
||||
drawer.image(filteredImage)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,28 +5,26 @@ import org.openrndr.extensions.SingleScreenshot
|
||||
import org.openrndr.extra.fx.distort.FluidDistort
|
||||
import org.openrndr.extra.fx.patterns.Checkers
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val fd = FluidDistort()
|
||||
val checkers = Checkers()
|
||||
fun main() = application {
|
||||
program {
|
||||
val fd = FluidDistort()
|
||||
val checkers = Checkers()
|
||||
|
||||
val image = colorBuffer(width, height)
|
||||
val distorted = image.createEquivalent()
|
||||
checkers.size = 64.0
|
||||
checkers.apply(emptyArray(), image)
|
||||
val image = colorBuffer(width, height)
|
||||
val distorted = image.createEquivalent()
|
||||
checkers.size = 64.0
|
||||
checkers.apply(emptyArray(), image)
|
||||
|
||||
if (System.getProperty("takeScreenshot") == "true") {
|
||||
extensions.filterIsInstance<SingleScreenshot>().forEach {
|
||||
it.delayFrames = 150
|
||||
}
|
||||
}
|
||||
extend {
|
||||
// Ensure >0.01 for a better screenshot
|
||||
fd.blend = (mouse.position.x / width).coerceAtLeast(0.01)
|
||||
fd.apply(image, distorted)
|
||||
drawer.image(distorted)
|
||||
if (System.getProperty("takeScreenshot") == "true") {
|
||||
extensions.filterIsInstance<SingleScreenshot>().forEach {
|
||||
it.delayFrames = 150
|
||||
}
|
||||
}
|
||||
extend {
|
||||
// Ensure >0.01 for a better screenshot
|
||||
fd.blend = (mouse.position.x / width).coerceAtLeast(0.01)
|
||||
fd.apply(image, distorted)
|
||||
drawer.image(distorted)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +1,25 @@
|
||||
import org.openrndr.extra.fx.color.RgbToOkLab
|
||||
import org.openrndr.extra.fx.color.OkLabToRgb
|
||||
import org.openrndr.application
|
||||
import org.openrndr.draw.ColorType
|
||||
import org.openrndr.draw.createEquivalent
|
||||
import org.openrndr.draw.loadImage
|
||||
import org.openrndr.extra.fx.color.OkLabToRgb
|
||||
import org.openrndr.extra.fx.color.RgbToOkLab
|
||||
|
||||
/**
|
||||
* This demonstrates converting a [ColorBuffer] from and to (OK)LAB color space using the [RgbToOkLab] and [OkLabToRgb]
|
||||
* filters. The (OK)Lab representation is signed and requires a floating point representation.
|
||||
*/
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val rgbToOkLab = RgbToOkLab()
|
||||
val okLabToRgb = OkLabToRgb()
|
||||
val image = loadImage("demo-data/images/image-001.png")
|
||||
val labImage = image.createEquivalent(type = ColorType.FLOAT32)
|
||||
rgbToOkLab.apply(image, labImage)
|
||||
okLabToRgb.apply(labImage, image)
|
||||
extend {
|
||||
drawer.image(image)
|
||||
}
|
||||
fun main() = application {
|
||||
program {
|
||||
val rgbToOkLab = RgbToOkLab()
|
||||
val okLabToRgb = OkLabToRgb()
|
||||
val image = loadImage("demo-data/images/image-001.png")
|
||||
val labImage = image.createEquivalent(type = ColorType.FLOAT32)
|
||||
rgbToOkLab.apply(image, labImage)
|
||||
okLabToRgb.apply(labImage, image)
|
||||
extend {
|
||||
drawer.image(image)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,38 +8,36 @@ import org.openrndr.extra.fx.patterns.Checkers
|
||||
import org.openrndr.math.Vector2
|
||||
import kotlin.math.sin
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
val a = drawImage(width, height) {
|
||||
drawer.stroke = null
|
||||
drawer.fill = ColorRGBa.BLUE
|
||||
drawer.circle(drawer.bounds.center - Vector2(100.0, 0.0), drawer.width * 0.25)
|
||||
}
|
||||
program {
|
||||
val a = drawImage(width, height) {
|
||||
drawer.stroke = null
|
||||
drawer.fill = ColorRGBa.BLUE
|
||||
drawer.circle(drawer.bounds.center - Vector2(100.0, 0.0), drawer.width * 0.25)
|
||||
}
|
||||
val b = drawImage(width, height) {
|
||||
drawer.clear(ColorRGBa.TRANSPARENT)
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.strokeWeight = 10.0
|
||||
drawer.fill = ColorRGBa.YELLOW.opacify(1.0)
|
||||
drawer.circle(drawer.bounds.center + Vector2(100.0, 0.0), drawer.width * 0.25)
|
||||
}
|
||||
BoxBlur().apply { window = 10 }.apply(b, b)
|
||||
val checked = a.createEquivalent()
|
||||
Checkers().apply(emptyArray(), checked)
|
||||
val b = drawImage(width, height) {
|
||||
drawer.clear(ColorRGBa.TRANSPARENT)
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.strokeWeight = 10.0
|
||||
drawer.fill = ColorRGBa.YELLOW.opacify(1.0)
|
||||
drawer.circle(drawer.bounds.center + Vector2(100.0, 0.0), drawer.width * 0.25)
|
||||
}
|
||||
BoxBlur().apply { window = 10 }.apply(b, b)
|
||||
val checked = a.createEquivalent()
|
||||
Checkers().apply(emptyArray(), checked)
|
||||
|
||||
val mixed = a.createEquivalent()
|
||||
val blendSpectral = BlendSpectral()
|
||||
extend {
|
||||
drawer.image(checked)
|
||||
blendSpectral.fill = sin(seconds) * 0.5 + 0.5
|
||||
blendSpectral.clip = seconds.mod(4.0) > 2.0
|
||||
blendSpectral.apply(a, b, mixed)
|
||||
drawer.image(mixed)
|
||||
}
|
||||
val mixed = a.createEquivalent()
|
||||
val blendSpectral = BlendSpectral()
|
||||
extend {
|
||||
drawer.image(checked)
|
||||
blendSpectral.fill = sin(seconds) * 0.5 + 0.5
|
||||
blendSpectral.clip = seconds.mod(4.0) > 2.0
|
||||
blendSpectral.apply(a, b, mixed)
|
||||
drawer.image(mixed)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,21 +10,19 @@ import kotlin.random.Random
|
||||
* - Filters the generated points to enforce a minimum distance of 20.0 units between them.
|
||||
* - Visualizes the filtered points as circles with a radius of 10.0 units on the canvas.
|
||||
*/
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val r = Random(0)
|
||||
val points = (0 until 10000).map {
|
||||
drawer.bounds.uniform(random = r)
|
||||
}
|
||||
program {
|
||||
val r = Random(0)
|
||||
val points = (0 until 10000).map {
|
||||
drawer.bounds.uniform(random = r)
|
||||
}
|
||||
val filteredPoints = points.filter(20.0)
|
||||
extend {
|
||||
drawer.circles(filteredPoints, 10.0)
|
||||
}
|
||||
val filteredPoints = points.filter(20.0)
|
||||
extend {
|
||||
drawer.circles(filteredPoints, 10.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,32 +13,29 @@ import kotlin.random.Random
|
||||
* - Rectangles representing the bounds of the cells in the grid.
|
||||
* - Circles representing the generated points.
|
||||
*/
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val r = Random(0)
|
||||
val hashGrid = HashGrid(72.0)
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val r = Random(0)
|
||||
val hashGrid = HashGrid(72.0)
|
||||
|
||||
extend {
|
||||
for (i in 0 until 100) {
|
||||
val p = drawer.bounds.uniform(random = r)
|
||||
if (hashGrid.isFree(p)) {
|
||||
hashGrid.insert(p)
|
||||
}
|
||||
extend {
|
||||
for (i in 0 until 100) {
|
||||
val p = drawer.bounds.uniform(random = r)
|
||||
if (hashGrid.isFree(p)) {
|
||||
hashGrid.insert(p)
|
||||
}
|
||||
|
||||
drawer.fill = null
|
||||
drawer.stroke = ColorRGBa.WHITE
|
||||
drawer.rectangles(hashGrid.cells().map { it.bounds }.toList())
|
||||
drawer.fill = null
|
||||
drawer.stroke = ColorRGBa.PINK
|
||||
drawer.circles(hashGrid.points().map { it.first }.toList(), 36.0)
|
||||
|
||||
}
|
||||
|
||||
drawer.fill = null
|
||||
drawer.stroke = ColorRGBa.WHITE
|
||||
drawer.rectangles(hashGrid.cells().map { it.bounds }.toList())
|
||||
drawer.fill = null
|
||||
drawer.stroke = ColorRGBa.PINK
|
||||
drawer.circles(hashGrid.points().map { it.first }.toList(), 36.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,52 +12,54 @@ import org.openrndr.draw.loadImage
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
// Load an image, convert to BoofCV format using orx-boofcv
|
||||
val input = loadImage("demo-data/images/image-001.png").toGrayF32()
|
||||
fun main() = application {
|
||||
program {
|
||||
// Load an image, convert to BoofCV format using orx-boofcv
|
||||
val input = loadImage("demo-data/images/image-001.png").toGrayF32()
|
||||
|
||||
// BoofCV: calculate a good threshold for the loaded image
|
||||
val threshold = GThresholdImageOps.computeOtsu(input, 0.0, 255.0)
|
||||
// BoofCV: calculate a good threshold for the loaded image
|
||||
val threshold = GThresholdImageOps.computeOtsu(input, 0.0, 255.0)
|
||||
|
||||
// BoofCV: use the threshold to convert the image to black and white
|
||||
val binary = GrayU8(input.width, input.height)
|
||||
ThresholdImageOps.threshold(input, binary, threshold.toFloat(), false)
|
||||
// BoofCV: use the threshold to convert the image to black and white
|
||||
val binary = GrayU8(input.width, input.height)
|
||||
ThresholdImageOps.threshold(input, binary, threshold.toFloat(), false)
|
||||
|
||||
// BoofCV: Contract and expand the white areas to remove noise
|
||||
var filtered = BinaryImageOps.erode8(binary, 1, null)
|
||||
filtered = BinaryImageOps.dilate8(filtered, 1, null)
|
||||
// BoofCV: Contract and expand the white areas to remove noise
|
||||
var filtered = BinaryImageOps.erode8(binary, 1, null)
|
||||
filtered = BinaryImageOps.dilate8(filtered, 1, null)
|
||||
|
||||
// BoofCV: Calculate contours as vector data
|
||||
val contours = BinaryImageOps.contour(filtered, ConnectRule.EIGHT, null)
|
||||
// BoofCV: Calculate contours as vector data
|
||||
val contours = BinaryImageOps.contour(filtered, ConnectRule.EIGHT, null)
|
||||
|
||||
// orx-boofcv: convert vector data to OPENRNDR ShapeContours
|
||||
val externalShapes = contours.toShapeContours(true,
|
||||
internal = false, external = true)
|
||||
val internalShapes = contours.toShapeContours(true,
|
||||
internal = true, external = false)
|
||||
// orx-boofcv: convert vector data to OPENRNDR ShapeContours
|
||||
val externalShapes = contours.toShapeContours(
|
||||
true,
|
||||
internal = false, external = true
|
||||
)
|
||||
val internalShapes = contours.toShapeContours(
|
||||
true,
|
||||
internal = true, external = false
|
||||
)
|
||||
|
||||
extend {
|
||||
drawer.run {
|
||||
// Zoom in and out over time
|
||||
translate(bounds.center)
|
||||
scale(1.5 + 0.5 * cos(seconds * 0.2))
|
||||
translate(-bounds.center)
|
||||
extend {
|
||||
drawer.run {
|
||||
// Zoom in and out over time
|
||||
translate(bounds.center)
|
||||
scale(1.5 + 0.5 * cos(seconds * 0.2))
|
||||
translate(-bounds.center)
|
||||
|
||||
stroke = null
|
||||
stroke = null
|
||||
|
||||
// Draw all external shapes
|
||||
fill = rgb(0.2)
|
||||
contours(externalShapes)
|
||||
// Draw all external shapes
|
||||
fill = rgb(0.2)
|
||||
contours(externalShapes)
|
||||
|
||||
// Draw internal shapes one by one to set unique colors
|
||||
internalShapes.forEachIndexed { i, shp ->
|
||||
val shade = 0.2 + (i % 7) * 0.1 +
|
||||
0.1 * sin(i + seconds)
|
||||
fill = ColorRGBa.PINK.shade(shade)
|
||||
contour(shp)
|
||||
}
|
||||
// Draw internal shapes one by one to set unique colors
|
||||
internalShapes.forEachIndexed { i, shp ->
|
||||
val shade = 0.2 + (i % 7) * 0.1 +
|
||||
0.1 * sin(i + seconds)
|
||||
fill = ColorRGBa.PINK.shade(shade)
|
||||
contour(shp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,24 +3,21 @@ import org.openrndr.boofcv.binding.resizeBy
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.draw.loadImage
|
||||
|
||||
fun main() = application {
|
||||
program {
|
||||
// Load an image, convert to BoofCV format using orx-boofcv
|
||||
val input = loadImage("demo-data/images/image-001.png")
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
// Load an image, convert to BoofCV format using orx-boofcv
|
||||
val input = loadImage("demo-data/images/image-001.png")
|
||||
val scaled = input.resizeBy(0.5)
|
||||
val scaled2 = input.resizeBy(0.25, convertToGray = true)
|
||||
val scaled3 = input.resizeBy(0.1)
|
||||
|
||||
val scaled = input.resizeBy(0.5)
|
||||
val scaled2 = input.resizeBy(0.25, convertToGray = true)
|
||||
val scaled3 = input.resizeBy(0.1)
|
||||
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
drawer.translate(0.0, (height - scaled.bounds.height) / 2.0)
|
||||
drawer.image(scaled)
|
||||
drawer.image(scaled2, scaled.bounds.width, scaled.bounds.height - scaled2.height)
|
||||
drawer.image(scaled3, scaled.bounds.width + scaled2.bounds.width, scaled.bounds.height - scaled3.height)
|
||||
}
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
drawer.translate(0.0, (height - scaled.bounds.height) / 2.0)
|
||||
drawer.image(scaled)
|
||||
drawer.image(scaled2, scaled.bounds.width, scaled.bounds.height - scaled2.height)
|
||||
drawer.image(scaled3, scaled.bounds.width + scaled2.bounds.width, scaled.bounds.height - scaled3.height)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,23 +3,20 @@ import org.openrndr.boofcv.binding.resizeTo
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.draw.loadImage
|
||||
|
||||
fun main() = application {
|
||||
program {
|
||||
// Load an image, convert to BoofCV format using orx-boofcv
|
||||
val input = loadImage("demo-data/images/image-001.png")
|
||||
val scaled = input.resizeTo(input.width / 3)
|
||||
val scaled2 = input.resizeTo(newHeight = input.height / 4, convertToGray = true)
|
||||
val scaled3 = input.resizeTo(input.width / 5, input.height / 5)
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
// Load an image, convert to BoofCV format using orx-boofcv
|
||||
val input = loadImage("demo-data/images/image-001.png")
|
||||
val scaled = input.resizeTo(input.width / 3)
|
||||
val scaled2 = input.resizeTo(newHeight = input.height / 4, convertToGray = true)
|
||||
val scaled3 = input.resizeTo(input.width / 5, input.height / 5)
|
||||
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
drawer.translate(0.0, (height - scaled.bounds.height) / 2.0)
|
||||
drawer.image(scaled)
|
||||
drawer.image(scaled2, scaled.bounds.width, scaled.bounds.height - scaled2.height)
|
||||
drawer.image(scaled3, scaled.bounds.width + scaled2.bounds.width, scaled.bounds.height - scaled3.height)
|
||||
}
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
drawer.translate(0.0, (height - scaled.bounds.height) / 2.0)
|
||||
drawer.image(scaled)
|
||||
drawer.image(scaled2, scaled.bounds.width, scaled.bounds.height - scaled2.height)
|
||||
drawer.image(scaled3, scaled.bounds.width + scaled2.bounds.width, scaled.bounds.height - scaled3.height)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,63 +17,65 @@ import org.openrndr.math.Vector2
|
||||
import org.openrndr.shape.Rectangle
|
||||
import org.openrndr.shape.ShapeContour
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
// Create a buffer where to draw something for boofcv
|
||||
val rt = renderTarget(width, height) {
|
||||
colorBuffer()
|
||||
depthBuffer()
|
||||
}
|
||||
// Draw some shapes on that buffer
|
||||
drawer.isolatedWithTarget(rt) {
|
||||
clear(ColorRGBa.BLACK)
|
||||
fill = ColorRGBa.WHITE
|
||||
stroke = null
|
||||
rectangle(Rectangle.fromCenter(bounds.position(0.33, 0.5),
|
||||
150.0, 150.0))
|
||||
translate(bounds.position(0.62, 0.5))
|
||||
rotate(30.0)
|
||||
rectangle(Rectangle.fromCenter(Vector2.ZERO, 200.0, 200.0))
|
||||
rectangle(0.0, -200.0, 60.0, 60.0)
|
||||
circle(0.0, 190.0, 60.0)
|
||||
}
|
||||
// Convert the bitmap buffer into ShapeContours
|
||||
val vectorized = imageToContours(rt.colorBuffer(0))
|
||||
fun main() = application {
|
||||
program {
|
||||
// Create a buffer where to draw something for boofcv
|
||||
val rt = renderTarget(width, height) {
|
||||
colorBuffer()
|
||||
depthBuffer()
|
||||
}
|
||||
// Draw some shapes on that buffer
|
||||
drawer.isolatedWithTarget(rt) {
|
||||
clear(ColorRGBa.BLACK)
|
||||
fill = ColorRGBa.WHITE
|
||||
stroke = null
|
||||
rectangle(
|
||||
Rectangle.fromCenter(
|
||||
bounds.position(0.33, 0.5),
|
||||
150.0, 150.0
|
||||
)
|
||||
)
|
||||
translate(bounds.position(0.62, 0.5))
|
||||
rotate(30.0)
|
||||
rectangle(Rectangle.fromCenter(Vector2.ZERO, 200.0, 200.0))
|
||||
rectangle(0.0, -200.0, 60.0, 60.0)
|
||||
circle(0.0, 190.0, 60.0)
|
||||
}
|
||||
// Convert the bitmap buffer into ShapeContours
|
||||
val vectorized = imageToContours(rt.colorBuffer(0))
|
||||
|
||||
// Show amount of segments in each shape (high number)
|
||||
vectorized.forEachIndexed { i, it ->
|
||||
println("boofcv shape $i: ${it.segments.size} segments")
|
||||
}
|
||||
// Show amount of segments in each shape (high number)
|
||||
vectorized.forEachIndexed { i, it ->
|
||||
println("boofcv shape $i: ${it.segments.size} segments")
|
||||
}
|
||||
|
||||
// Make a simplified list of points
|
||||
val simplePoints = vectorized.map {
|
||||
simplify(it.adaptivePositions(), 4.0)
|
||||
}.filter { it.size >= 3 }
|
||||
// Make a simplified list of points
|
||||
val simplePoints = vectorized.map {
|
||||
simplify(it.adaptivePositions(), 4.0)
|
||||
}.filter { it.size >= 3 }
|
||||
|
||||
// Use the simplified list to make a smooth contour
|
||||
val smooth = simplePoints.map {
|
||||
CatmullRomChain2(it, 0.0, true).toContour()
|
||||
}
|
||||
// Use the simplified list to make a smooth contour
|
||||
val smooth = simplePoints.map {
|
||||
CatmullRomChain2(it, 0.0, true).toContour()
|
||||
}
|
||||
|
||||
// Use the simplified list to make a polygonal contour
|
||||
val polygonal = simplePoints.map {
|
||||
ShapeContour.fromPoints(it, true)
|
||||
}
|
||||
// Use the simplified list to make a polygonal contour
|
||||
val polygonal = simplePoints.map {
|
||||
ShapeContour.fromPoints(it, true)
|
||||
}
|
||||
|
||||
// Show amount of segments in simplified shapes (low number).
|
||||
// Note: `smooth` and `polygonal` have the same number of segments
|
||||
smooth.forEachIndexed { i, it ->
|
||||
println("simplified shape $i: ${it.segments.size} segments")
|
||||
}
|
||||
// Show amount of segments in simplified shapes (low number).
|
||||
// Note: `smooth` and `polygonal` have the same number of segments
|
||||
smooth.forEachIndexed { i, it ->
|
||||
println("simplified shape $i: ${it.segments.size} segments")
|
||||
}
|
||||
|
||||
extend {
|
||||
drawer.run {
|
||||
fill = null // ColorRGBa.PINK.opacify(0.15)
|
||||
stroke = ColorRGBa.PINK.opacify(0.7)
|
||||
contours(polygonal)
|
||||
contours(smooth)
|
||||
}
|
||||
extend {
|
||||
drawer.run {
|
||||
fill = null // ColorRGBa.PINK.opacify(0.15)
|
||||
stroke = ColorRGBa.PINK.opacify(0.7)
|
||||
contours(polygonal)
|
||||
contours(smooth)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ private fun SceneRenderer.processVoxelConeTracing(drawer: Drawer, scene: Scene,
|
||||
val position = Vector3.ZERO
|
||||
drawer.lookAt(position + side.forward*40.0, position , side.up)
|
||||
drawPass(drawer, pass, materialContext, context) {
|
||||
it.parameter("voxelMap", feature.voxelMap!!.imageBinding(0, ImageAccess.WRITE))
|
||||
it.image("voxelMap", feature.voxelMap!!.imageBinding(0, ImageAccess.WRITE))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,25 +4,23 @@ import org.openrndr.extra.parameters.Description
|
||||
import org.openrndr.extra.parameters.PathParameter
|
||||
import org.openrndr.extra.propertywatchers.watchingImagePath
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val gui = GUI()
|
||||
gui.compartmentsCollapsedByDefault = false
|
||||
fun main() = application {
|
||||
program {
|
||||
val gui = GUI()
|
||||
gui.compartmentsCollapsedByDefault = false
|
||||
|
||||
val settings = @Description("Settings") object {
|
||||
@PathParameter("image", extensions = ["jpg", "png"], order = 10)
|
||||
var imagePath = "demo-data/images/image-001.png"
|
||||
val settings = @Description("Settings") object {
|
||||
@PathParameter("image", extensions = ["jpg", "png"], order = 10)
|
||||
var imagePath = "demo-data/images/image-001.png"
|
||||
|
||||
val image by watchingImagePath(::imagePath) {
|
||||
it
|
||||
}
|
||||
}
|
||||
gui.add(settings)
|
||||
extend(gui)
|
||||
extend {
|
||||
drawer.image(settings.image)
|
||||
val image by watchingImagePath(::imagePath) {
|
||||
it
|
||||
}
|
||||
}
|
||||
gui.add(settings)
|
||||
extend(gui)
|
||||
extend {
|
||||
drawer.image(settings.image)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import org.openrndr.*
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.dialogs.*
|
||||
import org.openrndr.draw.Drawer
|
||||
import org.openrndr.extra.noise.random
|
||||
import org.openrndr.extra.noise.uniform
|
||||
import org.openrndr.extra.parameters.*
|
||||
import org.openrndr.internal.Driver
|
||||
@@ -1077,7 +1076,7 @@ open class GUI(
|
||||
val min = parameter.doubleRange!!.start
|
||||
val max = parameter.doubleRange!!.endInclusive
|
||||
val currentValue = (parameter.property as KMutableProperty1<Any, Double>).get(labeledObject.obj)
|
||||
val randomValue = random(min, max)
|
||||
val randomValue = Double.uniform(min, max)
|
||||
val newValue = mix(currentValue, randomValue, strength)
|
||||
(parameter.property as KMutableProperty1<Any, Double>).set(labeledObject.obj, newValue)
|
||||
}
|
||||
@@ -1086,7 +1085,7 @@ open class GUI(
|
||||
val min = parameter.intRange!!.first
|
||||
val max = parameter.intRange!!.last
|
||||
val currentValue = (parameter.property as KMutableProperty1<Any, Int>).get(labeledObject.obj)
|
||||
val randomValue = random(min.toDouble(), max.toDouble())
|
||||
val randomValue = Double.uniform(min.toDouble(), max.toDouble())
|
||||
val newValue = mix(currentValue.toDouble(), randomValue, strength).roundToInt()
|
||||
(parameter.property as KMutableProperty1<Any, Int>).set(labeledObject.obj, newValue)
|
||||
}
|
||||
|
||||
@@ -9,33 +9,31 @@ import org.openrndr.math.Vector2
|
||||
/**
|
||||
* Demonstration of two-way binding using [bindMidiControl]
|
||||
*/
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val midi = openMidiDevice("MIDI2x2 [hw:3,0,0]")
|
||||
val settings = object {
|
||||
@DoubleParameter("radius", 0.0, 100.0)
|
||||
var radius = 0.0
|
||||
fun main() = application {
|
||||
program {
|
||||
val midi = openMidiDevice("MIDI2x2 [hw:3,0,0]")
|
||||
val settings = object {
|
||||
@DoubleParameter("radius", 0.0, 100.0)
|
||||
var radius = 0.0
|
||||
|
||||
@DoubleParameter("x", -100.0, 100.0)
|
||||
var x = 0.0
|
||||
@DoubleParameter("x", -100.0, 100.0)
|
||||
var x = 0.0
|
||||
|
||||
@DoubleParameter("y", -100.0, 100.0)
|
||||
var y = 0.0
|
||||
@DoubleParameter("y", -100.0, 100.0)
|
||||
var y = 0.0
|
||||
|
||||
@ColorParameter("fill")
|
||||
var color = ColorRGBa.WHITE
|
||||
}
|
||||
@ColorParameter("fill")
|
||||
var color = ColorRGBa.WHITE
|
||||
}
|
||||
|
||||
bindMidiControl(settings::radius, midi, 0, 1)
|
||||
bindMidiControl(settings::x, midi, 0, 2)
|
||||
bindMidiControl(settings::y, midi, 0, 3)
|
||||
bindMidiControl(settings::color, midi, 0, 4)
|
||||
bindMidiControl(settings::radius, midi, 0, 1)
|
||||
bindMidiControl(settings::x, midi, 0, 2)
|
||||
bindMidiControl(settings::y, midi, 0, 3)
|
||||
bindMidiControl(settings::color, midi, 0, 4)
|
||||
|
||||
extend {
|
||||
drawer.fill = settings.color
|
||||
drawer.circle(drawer.bounds.center + Vector2(settings.x, settings.y), settings.radius)
|
||||
}
|
||||
extend {
|
||||
drawer.fill = settings.color
|
||||
drawer.circle(drawer.bounds.center + Vector2(settings.x, settings.y), settings.radius)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,14 +6,12 @@ import org.openrndr.extra.midi.openMidiDevice
|
||||
/**
|
||||
* Demonstration of [MidiConsole]
|
||||
*/
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
listMidiDevices().forEach { println(it.toString()) }
|
||||
val midi = openMidiDevice("Launchpad [hw:4,0,0]")
|
||||
extend(MidiConsole()) {
|
||||
register(midi)
|
||||
}
|
||||
fun main() = application {
|
||||
program {
|
||||
listMidiDevices().forEach { println(it.toString()) }
|
||||
val midi = openMidiDevice("Launchpad [hw:4,0,0]")
|
||||
extend(MidiConsole()) {
|
||||
register(midi)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,95 +13,93 @@ import kotlin.random.Random
|
||||
* Hold the mouse button to randomize the frequencies.
|
||||
* Press keys 'a' or 'b' for less random frequencies.
|
||||
*/
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val minim = minim()
|
||||
val out = minim.lineOut
|
||||
fun main() = application {
|
||||
program {
|
||||
val minim = minim()
|
||||
val out = minim.lineOut
|
||||
|
||||
if (out == null) {
|
||||
application.exit()
|
||||
if (out == null) {
|
||||
application.exit()
|
||||
}
|
||||
|
||||
// generates a random frequency value biased down
|
||||
fun randomFreq() = 20f + Random.nextFloat().pow(3) * 1000
|
||||
|
||||
// If one didn't want to visualize or control the synths we
|
||||
// wouldn't need a data structure to store them. Here we store
|
||||
// Pairs, so we have access both to the frequency of the wave
|
||||
// and the current amplitude defined by the lfo (low frequency
|
||||
// oscillator).
|
||||
val synths = List(20) {
|
||||
// By default, Oscil creates sine waves, but it can be changed.
|
||||
val lfo = Oscil(
|
||||
Random.nextFloat() * 0.1f + 0.005f,
|
||||
0.05f
|
||||
).apply {
|
||||
// Here we set the center of the lfo to 0.05f.
|
||||
// Since the amplitude is also 0.05f, it moves between
|
||||
// 0.00f and 0.10f.
|
||||
offset.lastValue = 0.05f
|
||||
|
||||
// Have the sine waves to not start in sync.
|
||||
//phase.lastValue = Random.nextFloat() * 6.28f
|
||||
}
|
||||
val wave = Oscil(randomFreq(), 0f)
|
||||
// The `lfo` Oscil controls the `wave` Oscil's amplitude.
|
||||
lfo.patch(wave.amplitude)
|
||||
// Random pan to avoid a mono sound.
|
||||
val pan = Pan(Random.nextFloat() * 2 - 1)
|
||||
wave.patch(pan)
|
||||
pan.patch(out)
|
||||
// Store a [Pair] in `synths`.
|
||||
Pair(wave, lfo)
|
||||
}
|
||||
val bgColor = rgb(0.094, 0.188, 0.349)
|
||||
val lineColor = rgb(0.992, 0.918, 0.671)
|
||||
val mouseTracker = MouseTracker(mouse)
|
||||
|
||||
// generates a random frequency value biased down
|
||||
fun randomFreq() = 20f + Random.nextFloat().pow(3) * 1000
|
||||
|
||||
// If one didn't want to visualize or control the synths we
|
||||
// wouldn't need a data structure to store them. Here we store
|
||||
// Pairs, so we have access both to the frequency of the wave
|
||||
// and the current amplitude defined by the lfo (low frequency
|
||||
// oscillator).
|
||||
val synths = List(20) {
|
||||
// By default, Oscil creates sine waves, but it can be changed.
|
||||
val lfo = Oscil(
|
||||
Random.nextFloat() * 0.1f + 0.005f,
|
||||
0.05f
|
||||
).apply {
|
||||
// Here we set the center of the lfo to 0.05f.
|
||||
// Since the amplitude is also 0.05f, it moves between
|
||||
// 0.00f and 0.10f.
|
||||
offset.lastValue = 0.05f
|
||||
|
||||
// Have the sine waves to not start in sync.
|
||||
//phase.lastValue = Random.nextFloat() * 6.28f
|
||||
extend {
|
||||
drawer.clear(bgColor)
|
||||
drawer.translate(drawer.bounds.center)
|
||||
drawer.rotate(seconds)
|
||||
// A CircleBatchBuilder for faster drawing of circles.
|
||||
drawer.circles {
|
||||
// For each synth draw a circle.
|
||||
synths.forEachIndexed { i, (wave, lfo) ->
|
||||
stroke = lineColor.opacify(Random.nextDouble(0.4) + 0.6)
|
||||
fill = lineColor.opacify(Random.nextDouble() * 0.04)
|
||||
// A Polar arrangement centered on the screen.
|
||||
// Higher pitch circles are farther away from the center.
|
||||
val pos = Polar(
|
||||
360.0 * i / synths.size,
|
||||
50.0 + wave.frequency.lastValue * 0.2
|
||||
).cartesian
|
||||
// The size of the circle depends on the current volume
|
||||
// set by the lfo.
|
||||
circle(pos, 500 * lfo.lastValues.last().toDouble())
|
||||
}
|
||||
val wave = Oscil(randomFreq(), 0f)
|
||||
// The `lfo` Oscil controls the `wave` Oscil's amplitude.
|
||||
lfo.patch(wave.amplitude)
|
||||
// Random pan to avoid a mono sound.
|
||||
val pan = Pan(Random.nextFloat() * 2 - 1)
|
||||
wave.patch(pan)
|
||||
pan.patch(out)
|
||||
// Store a [Pair] in `synths`.
|
||||
Pair(wave, lfo)
|
||||
}
|
||||
val bgColor = rgb(0.094, 0.188, 0.349)
|
||||
val lineColor = rgb(0.992, 0.918, 0.671)
|
||||
val mouseTracker = MouseTracker(mouse)
|
||||
|
||||
extend {
|
||||
drawer.clear(bgColor)
|
||||
drawer.translate(drawer.bounds.center)
|
||||
drawer.rotate(seconds)
|
||||
// A CircleBatchBuilder for faster drawing of circles.
|
||||
drawer.circles {
|
||||
// For each synth draw a circle.
|
||||
synths.forEachIndexed { i, (wave, lfo) ->
|
||||
stroke = lineColor.opacify(Random.nextDouble(0.4) + 0.6)
|
||||
fill = lineColor.opacify(Random.nextDouble() * 0.04)
|
||||
// A Polar arrangement centered on the screen.
|
||||
// Higher pitch circles are farther away from the center.
|
||||
val pos = Polar(
|
||||
360.0 * i / synths.size,
|
||||
50.0 + wave.frequency.lastValue * 0.2
|
||||
).cartesian
|
||||
// The size of the circle depends on the current volume
|
||||
// set by the lfo.
|
||||
circle(pos, 500 * lfo.lastValues.last().toDouble())
|
||||
if (mouseTracker.pressedButtons.isNotEmpty()) {
|
||||
synths.random().first.setFrequency(randomFreq())
|
||||
}
|
||||
}
|
||||
keyboard.keyDown.listen { key ->
|
||||
when (key.name) {
|
||||
"a" -> {
|
||||
// make all frequencies close to a base frequency
|
||||
// (circular arrangement)
|
||||
val baseFreq = 20 + Random.nextFloat() * 200
|
||||
synths.forEach {
|
||||
it.first.setFrequency(baseFreq + Random.nextFloat() * 20)
|
||||
}
|
||||
}
|
||||
if (mouseTracker.pressedButtons.isNotEmpty()) {
|
||||
synths.random().first.setFrequency(randomFreq())
|
||||
}
|
||||
}
|
||||
keyboard.keyDown.listen { key ->
|
||||
when (key.name) {
|
||||
"a" -> {
|
||||
// make all frequencies close to a base frequency
|
||||
// (circular arrangement)
|
||||
val baseFreq = 20 + Random.nextFloat() * 200
|
||||
synths.forEach {
|
||||
it.first.setFrequency(baseFreq + Random.nextFloat() * 20)
|
||||
}
|
||||
}
|
||||
|
||||
"b" -> {
|
||||
// make all frequencies follow an exponential series
|
||||
// (spiral arrangement)
|
||||
val inc = Random.nextFloat() * 0.1f
|
||||
synths.forEachIndexed { i, (wave, _) ->
|
||||
wave.setFrequency(25f.pow(1f + i * inc))
|
||||
}
|
||||
"b" -> {
|
||||
// make all frequencies follow an exponential series
|
||||
// (spiral arrangement)
|
||||
val inc = Random.nextFloat() * 0.1f
|
||||
synths.forEachIndexed { i, (wave, _) ->
|
||||
wave.setFrequency(25f.pow(1f + i * inc))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +1,34 @@
|
||||
import ddf.minim.Minim
|
||||
import ddf.minim.analysis.FFT
|
||||
import ddf.minim.analysis.LanczosWindow
|
||||
|
||||
import org.openrndr.application
|
||||
import org.openrndr.extra.minim.minim
|
||||
import org.openrndr.math.map
|
||||
import kotlin.math.ln
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 1280
|
||||
height = 720
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 1280
|
||||
height = 720
|
||||
}
|
||||
|
||||
program {
|
||||
val minim = minim()
|
||||
if (minim.lineOut == null) {
|
||||
application.exit()
|
||||
}
|
||||
|
||||
program {
|
||||
val minim = minim()
|
||||
if (minim.lineOut == null) {
|
||||
application.exit()
|
||||
}
|
||||
|
||||
val lineIn = minim.getLineIn(Minim.MONO, 2048, 48000f)
|
||||
if (lineIn == null) {
|
||||
application.exit()
|
||||
}
|
||||
val fft = FFT(lineIn.bufferSize(), lineIn.sampleRate())
|
||||
fft.window(LanczosWindow())
|
||||
extend {
|
||||
fft.forward(lineIn.mix)
|
||||
for (i in 0 until 200) {
|
||||
val bandDB = 20.0 * ln(2.0 * fft.getBand(i) / fft.timeSize())
|
||||
drawer.rectangle(i * 5.0, height / 2.0, 5.0, bandDB.map(0.0, -150.0, 0.0, -height / 8.0))
|
||||
}
|
||||
val lineIn = minim.getLineIn(Minim.MONO, 2048, 48000f)
|
||||
if (lineIn == null) {
|
||||
application.exit()
|
||||
}
|
||||
val fft = FFT(lineIn.bufferSize(), lineIn.sampleRate())
|
||||
fft.window(LanczosWindow())
|
||||
extend {
|
||||
fft.forward(lineIn.mix)
|
||||
for (i in 0 until 200) {
|
||||
val bandDB = 20.0 * ln(2.0 * fft.getBand(i) / fft.timeSize())
|
||||
drawer.rectangle(i * 5.0, height / 2.0, 5.0, bandDB.map(0.0, -150.0, 0.0, -height / 8.0))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +1,25 @@
|
||||
import org.openrndr.application
|
||||
import org.openrndr.extra.minim.minim
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val minim = minim()
|
||||
if (minim.lineOut == null) {
|
||||
application.exit()
|
||||
}
|
||||
fun main() = application {
|
||||
program {
|
||||
val minim = minim()
|
||||
if (minim.lineOut == null) {
|
||||
application.exit()
|
||||
}
|
||||
|
||||
val player = minim.loadFile(
|
||||
"demo-data/sounds/26777__junggle__btn402.mp3"
|
||||
)
|
||||
val player = minim.loadFile(
|
||||
"demo-data/sounds/26777__junggle__btn402.mp3"
|
||||
)
|
||||
|
||||
// fade gain to -40dB in 15 seconds
|
||||
player.shiftGain(player.gain, -40f, 15000)
|
||||
// fade gain to -40dB in 15 seconds
|
||||
player.shiftGain(player.gain, -40f, 15000)
|
||||
|
||||
extend {
|
||||
if(frameCount % 30 == 0) {
|
||||
player.rewind()
|
||||
//player.gain = Random.nextDouble(-20.0, 0.0).toFloat()
|
||||
player.play()
|
||||
}
|
||||
extend {
|
||||
if (frameCount % 30 == 0) {
|
||||
player.rewind()
|
||||
//player.gain = Random.nextDouble(-20.0, 0.0).toFloat()
|
||||
player.play()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,39 +8,37 @@ import kotlin.math.cos
|
||||
/**
|
||||
* Live-coding with [oliveProgram]
|
||||
*/
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 1280
|
||||
height = 720
|
||||
}
|
||||
oliveProgram {
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
drawer.fill = ColorRGBa.WHITE
|
||||
for (i in 0 until 100) {
|
||||
drawer.circle(
|
||||
width / 2.0 + cos(seconds + i) * 320.0,
|
||||
i * 7.2,
|
||||
cos(i + seconds * 0.5) * 20.0 + 20.0
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
// -- this is only needed for the automated screenshots
|
||||
.olive.scriptLoaded.listen {
|
||||
if (System.getProperty("takeScreenshot") == "true") {
|
||||
// -- this is a bit of hack, we need to push the screenshot extension in front of the olive one
|
||||
fun <T : Extension> extendHead(extension: T, configure: T.() -> Unit): T {
|
||||
program.extensions.add(0, extension)
|
||||
extension.configure()
|
||||
extension.setup(program)
|
||||
return extension
|
||||
}
|
||||
extendHead(SingleScreenshot()) {
|
||||
this.outputFile = System.getProperty("screenshotPath")
|
||||
}
|
||||
}
|
||||
}
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 1280
|
||||
height = 720
|
||||
}
|
||||
oliveProgram {
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
drawer.fill = ColorRGBa.WHITE
|
||||
for (i in 0 until 100) {
|
||||
drawer.circle(
|
||||
width / 2.0 + cos(seconds + i) * 320.0,
|
||||
i * 7.2,
|
||||
cos(i + seconds * 0.5) * 20.0 + 20.0
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
// -- this is only needed for the automated screenshots
|
||||
.olive.scriptLoaded.listen {
|
||||
if (System.getProperty("takeScreenshot") == "true") {
|
||||
// -- this is a bit of hack, we need to push the screenshot extension in front of the olive one
|
||||
fun <T : Extension> extendHead(extension: T, configure: T.() -> Unit): T {
|
||||
program.extensions.add(0, extension)
|
||||
extension.configure()
|
||||
extension.setup(program)
|
||||
return extension
|
||||
}
|
||||
extendHead(SingleScreenshot()) {
|
||||
this.outputFile = System.getProperty("screenshotPath")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import org.openrndr.draw.colorBuffer
|
||||
import org.openrndr.draw.isolatedWithTarget
|
||||
import org.openrndr.draw.renderTarget
|
||||
import org.openrndr.extra.noise.Random
|
||||
import org.openrndr.extra.noise.uniform
|
||||
import org.openrndr.math.Polar
|
||||
import org.openrndr.math.clamp
|
||||
import org.openrndr.poissonfill.PoissonFill
|
||||
@@ -34,11 +35,11 @@ fun main() {
|
||||
val things = List(10) {
|
||||
Thing(
|
||||
ColorHSVa(it * 182.0,
|
||||
Random.double(0.3, 0.6),
|
||||
Random.double(0.1, 0.9)).toRGBa(),
|
||||
Polar(Random.double0(360.0),
|
||||
Double.uniform(0.3, 0.6),
|
||||
Double.uniform(0.1, 0.9)).toRGBa(),
|
||||
Polar(Double.uniform(0.0, 360.0),
|
||||
100.0 + it * 10.0),
|
||||
Polar(Random.double(-1.0, 1.0), 0.0))
|
||||
Polar(Double.uniform(-1.0, 1.0), 0.0))
|
||||
}
|
||||
val mouseTracker = MouseTracker(mouse)
|
||||
|
||||
|
||||
@@ -6,29 +6,27 @@ import org.openrndr.draw.colorBuffer
|
||||
import org.openrndr.draw.tint
|
||||
import org.openrndr.extra.realsense2.RS2Sensor
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val sensors = RS2Sensor.listSensors()
|
||||
val depthFrame = colorBuffer(640, 480, format = ColorFormat.R, type = ColorType.UINT16)
|
||||
for (sensor in sensors) {
|
||||
println(sensor)
|
||||
}
|
||||
val sensor = RS2Sensor.openFirstOrDummy()
|
||||
fun main() = application {
|
||||
program {
|
||||
val sensors = RS2Sensor.listSensors()
|
||||
val depthFrame = colorBuffer(640, 480, format = ColorFormat.R, type = ColorType.UINT16)
|
||||
for (sensor in sensors) {
|
||||
println(sensor)
|
||||
for (stream in sensor.streams) {
|
||||
println(stream.intrinsics)
|
||||
}
|
||||
}
|
||||
val sensor = RS2Sensor.openFirstOrDummy()
|
||||
println(sensor)
|
||||
for (stream in sensor.streams) {
|
||||
println(stream.intrinsics)
|
||||
}
|
||||
|
||||
|
||||
sensor.depthFrameReceived.listen {
|
||||
it.copyTo(depthFrame)
|
||||
}
|
||||
extend {
|
||||
sensor.waitForFrames()
|
||||
drawer.drawStyle.colorMatrix = tint(ColorRGBa.WHITE.shade(20.0))
|
||||
drawer.image(depthFrame)
|
||||
}
|
||||
sensor.depthFrameReceived.listen {
|
||||
it.copyTo(depthFrame)
|
||||
}
|
||||
extend {
|
||||
sensor.waitForFrames()
|
||||
drawer.drawStyle.colorMatrix = tint(ColorRGBa.WHITE.shade(20.0))
|
||||
drawer.image(depthFrame)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,34 +11,32 @@ import org.openrndr.extra.realsense2.RS2Sensor
|
||||
*
|
||||
* Tested with two sensors, only uses depth stream now
|
||||
*/
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 1280
|
||||
height = 720
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 1280
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val sensorDescriptions = RS2Sensor.listSensors()
|
||||
|
||||
val sensors = sensorDescriptions.map {
|
||||
it.open()
|
||||
}
|
||||
program {
|
||||
val sensorDescriptions = RS2Sensor.listSensors()
|
||||
|
||||
val sensors = sensorDescriptions.map {
|
||||
it.open()
|
||||
val depthFrames = sensors.map {
|
||||
colorBuffer(640, 480, format = ColorFormat.R, type = ColorType.UINT16)
|
||||
}
|
||||
sensors.forEachIndexed { index, it ->
|
||||
it.depthFrameReceived.listen {
|
||||
it.copyTo(depthFrames[index])
|
||||
}
|
||||
|
||||
val depthFrames = sensors.map {
|
||||
colorBuffer(640, 480, format = ColorFormat.R, type = ColorType.UINT16)
|
||||
}
|
||||
sensors.forEachIndexed { index, it ->
|
||||
it.depthFrameReceived.listen {
|
||||
it.copyTo(depthFrames[index])
|
||||
}
|
||||
}
|
||||
extend {
|
||||
drawer.drawStyle.colorMatrix = tint(ColorRGBa.WHITE.shade(20.0))
|
||||
for ((index, sensor) in sensors.withIndex()) {
|
||||
sensor.waitForFrames()
|
||||
drawer.image(depthFrames[index])
|
||||
drawer.translate(640.0, 0.0)
|
||||
}
|
||||
}
|
||||
extend {
|
||||
drawer.drawStyle.colorMatrix = tint(ColorRGBa.WHITE.shade(20.0))
|
||||
for ((index, sensor) in sensors.withIndex()) {
|
||||
sensor.waitForFrames()
|
||||
drawer.image(depthFrames[index])
|
||||
drawer.translate(640.0, 0.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import org.openrndr.application
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
fun main() = application {
|
||||
program {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,20 +6,13 @@ import org.openrndr.draw.shadeStyle
|
||||
import org.openrndr.extra.camera.Orbital
|
||||
import org.openrndr.extra.mesh.IIndexedPolygon
|
||||
import org.openrndr.extra.mesh.IVertexData
|
||||
import org.openrndr.extra.mesh.noise.nonuniform
|
||||
import org.openrndr.extra.mesh.noise.nonuniformHammersley
|
||||
import org.openrndr.extra.mesh.noise.nonuniformRSeq
|
||||
import org.openrndr.extra.objloader.loadOBJMeshData
|
||||
import org.openrndr.extra.mesh.noise.uniform
|
||||
import org.openrndr.extra.meshgenerators.normals.estimateNormals
|
||||
import org.openrndr.extra.meshgenerators.sphereMesh
|
||||
import org.openrndr.math.Spherical
|
||||
import org.openrndr.extra.objloader.loadOBJMeshData
|
||||
import org.openrndr.math.Vector3
|
||||
import java.io.File
|
||||
import kotlin.math.absoluteValue
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.sin
|
||||
import kotlin.random.Random
|
||||
|
||||
|
||||
|
||||
@@ -6,28 +6,26 @@ import org.openrndr.drawImage
|
||||
import org.openrndr.extra.propertywatchers.watchingImagePath
|
||||
import org.openrndr.extra.propertywatchers.watchingProperty
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val state = object {
|
||||
var path = "demo-data/images/image-001.png"
|
||||
val image by watchingImagePath(::path) {
|
||||
drawImage(it.width, it.height) {
|
||||
drawer.drawStyle.colorMatrix = grayscale()
|
||||
drawer.image(it)
|
||||
}
|
||||
}
|
||||
val redImage by watchingProperty(::image, cleaner = { it.destroy() }) {
|
||||
drawImage(it.width, it.height) {
|
||||
drawer.drawStyle.colorMatrix = tint(ColorRGBa.RED)
|
||||
drawer.image(it)
|
||||
}
|
||||
fun main() = application {
|
||||
program {
|
||||
val state = object {
|
||||
var path = "demo-data/images/image-001.png"
|
||||
val image by watchingImagePath(::path) {
|
||||
drawImage(it.width, it.height) {
|
||||
drawer.drawStyle.colorMatrix = grayscale()
|
||||
drawer.image(it)
|
||||
}
|
||||
}
|
||||
val redImage by watchingProperty(::image, cleaner = { it.destroy() }) {
|
||||
drawImage(it.width, it.height) {
|
||||
drawer.drawStyle.colorMatrix = tint(ColorRGBa.RED)
|
||||
drawer.image(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extend {
|
||||
drawer.image(state.redImage)
|
||||
}
|
||||
extend {
|
||||
drawer.image(state.redImage)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,20 @@
|
||||
import org.openrndr.application
|
||||
import org.openrndr.extra.propertywatchers.watchingProperty
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val state = object {
|
||||
val x by watchingProperty(mouse::position) {
|
||||
it.x
|
||||
}
|
||||
|
||||
val xx by watchingProperty(::x) {
|
||||
it * it
|
||||
}
|
||||
fun main() = application {
|
||||
program {
|
||||
val state = object {
|
||||
val x by watchingProperty(mouse::position) {
|
||||
it.x
|
||||
}
|
||||
|
||||
extend {
|
||||
state.x
|
||||
val xx by watchingProperty(::x) {
|
||||
it * it
|
||||
}
|
||||
}
|
||||
|
||||
extend {
|
||||
state.x
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,42 +7,40 @@ import org.openrndr.extra.quadtree.Quadtree
|
||||
import org.openrndr.math.Vector2
|
||||
import org.openrndr.shape.Rectangle
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
title = "QuadTree"
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
title = "QuadTree"
|
||||
}
|
||||
program {
|
||||
val box = Rectangle.fromCenter(Vector2(400.0), 750.0)
|
||||
|
||||
val points = (0 until 1_000).map {
|
||||
Vector2.gaussian(box.center, Vector2(95.0), Random.rnd)
|
||||
}
|
||||
program {
|
||||
val box = Rectangle.fromCenter(Vector2(400.0), 750.0)
|
||||
|
||||
val points = (0 until 1_000).map {
|
||||
Vector2.gaussian(box.center, Vector2(95.0), Random.rnd)
|
||||
}
|
||||
val quadTree = Quadtree<Vector2>(box) { it }
|
||||
|
||||
val quadTree = Quadtree<Vector2>(box) { it }
|
||||
for (point in points) {
|
||||
quadTree.insert(point)
|
||||
}
|
||||
|
||||
for (point in points) {
|
||||
quadTree.insert(point)
|
||||
}
|
||||
val batch = drawer.rectangleBatch {
|
||||
this.fill = null
|
||||
this.stroke = ColorRGBa.GRAY
|
||||
this.strokeWeight = 0.5
|
||||
quadTree.batch(this)
|
||||
}
|
||||
|
||||
val batch = drawer.rectangleBatch {
|
||||
this.fill = null
|
||||
this.stroke = ColorRGBa.GRAY
|
||||
this.strokeWeight = 0.5
|
||||
quadTree.batch(this)
|
||||
}
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
drawer.rectangles(batch)
|
||||
|
||||
drawer.rectangles(batch)
|
||||
|
||||
drawer.fill = ColorRGBa.PINK.opacify(0.7)
|
||||
drawer.stroke = null
|
||||
drawer.circles(points, 5.0)
|
||||
}
|
||||
drawer.fill = ColorRGBa.PINK.opacify(0.7)
|
||||
drawer.stroke = null
|
||||
drawer.circles(points, 5.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,68 +7,66 @@ import org.openrndr.extra.quadtree.Quadtree
|
||||
import org.openrndr.math.Vector2
|
||||
import org.openrndr.shape.Rectangle
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
title = "QuadTree"
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
title = "QuadTree"
|
||||
}
|
||||
program {
|
||||
val box = Rectangle.fromCenter(Vector2(400.0), 750.0)
|
||||
|
||||
val points = (0 until 100).map {
|
||||
Vector2.gaussian(box.center, Vector2(95.0), Random.rnd)
|
||||
}
|
||||
program {
|
||||
val box = Rectangle.fromCenter(Vector2(400.0), 750.0)
|
||||
|
||||
val points = (0 until 100).map {
|
||||
Vector2.gaussian(box.center, Vector2(95.0), Random.rnd)
|
||||
}
|
||||
val quadTree = Quadtree<Vector2>(box) { it }
|
||||
|
||||
val quadTree = Quadtree<Vector2>(box) { it }
|
||||
for (point in points) {
|
||||
quadTree.insert(point)
|
||||
}
|
||||
|
||||
for (point in points) {
|
||||
quadTree.insert(point)
|
||||
}
|
||||
val selected = points[3]
|
||||
val radius = 40.0
|
||||
|
||||
val selected = points[3]
|
||||
val radius = 40.0
|
||||
val nearestQuery = quadTree.nearest(selected, radius)
|
||||
|
||||
val nearestQuery = quadTree.nearest(selected, radius)
|
||||
val batch = drawer.rectangleBatch {
|
||||
this.fill = null
|
||||
this.stroke = ColorRGBa.GRAY
|
||||
this.strokeWeight = 0.5
|
||||
quadTree.batch(this)
|
||||
}
|
||||
|
||||
val batch = drawer.rectangleBatch {
|
||||
this.fill = null
|
||||
this.stroke = ColorRGBa.GRAY
|
||||
this.strokeWeight = 0.5
|
||||
quadTree.batch(this)
|
||||
}
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
drawer.rectangles(batch)
|
||||
|
||||
drawer.rectangles(batch)
|
||||
drawer.fill = ColorRGBa.PINK.opacify(0.7)
|
||||
drawer.stroke = null
|
||||
drawer.circles(points, 5.0)
|
||||
|
||||
drawer.fill = ColorRGBa.PINK.opacify(0.7)
|
||||
nearestQuery?.let { (nearest, neighbours, nodes) ->
|
||||
drawer.stroke = null
|
||||
drawer.circles(points, 5.0)
|
||||
drawer.fill = ColorRGBa.YELLOW.opacify(0.2)
|
||||
|
||||
nearestQuery?.let { (nearest, neighbours, nodes) ->
|
||||
drawer.stroke = null
|
||||
drawer.fill = ColorRGBa.YELLOW.opacify(0.2)
|
||||
|
||||
for (node in nodes) {
|
||||
node.draw(drawer)
|
||||
}
|
||||
|
||||
drawer.fill = ColorRGBa.GREEN.opacify(0.7)
|
||||
drawer.circles(neighbours, 5.0)
|
||||
|
||||
drawer.fill = ColorRGBa.RED.opacify(0.9)
|
||||
drawer.circle(nearest, 5.0)
|
||||
|
||||
drawer.fill = ColorRGBa.PINK
|
||||
drawer.circle(selected, 5.0)
|
||||
|
||||
drawer.stroke = ColorRGBa.PINK
|
||||
drawer.fill = null
|
||||
drawer.circle(selected, radius)
|
||||
for (node in nodes) {
|
||||
node.draw(drawer)
|
||||
}
|
||||
|
||||
drawer.fill = ColorRGBa.GREEN.opacify(0.7)
|
||||
drawer.circles(neighbours, 5.0)
|
||||
|
||||
drawer.fill = ColorRGBa.RED.opacify(0.9)
|
||||
drawer.circle(nearest, 5.0)
|
||||
|
||||
drawer.fill = ColorRGBa.PINK
|
||||
drawer.circle(selected, 5.0)
|
||||
|
||||
drawer.stroke = ColorRGBa.PINK
|
||||
drawer.fill = null
|
||||
drawer.circle(selected, radius)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,74 +9,78 @@ import org.openrndr.shape.Rectangle
|
||||
* Example of 5 gradient styles.
|
||||
* NPointLinear and NPoingGradient have separate demos.
|
||||
*/
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 1000
|
||||
height = 500
|
||||
}
|
||||
program {
|
||||
// Create gradients with initial colors
|
||||
val gradients = listOf(
|
||||
RadialGradient(ColorRGBa.PINK, ColorRGBa.WHITE),
|
||||
AngularGradient(ColorRGBa.PINK, ColorRGBa.WHITE),
|
||||
NPointGradient(Array(4) {
|
||||
ColorRGBa.PINK.shade(it / 3.0)
|
||||
}),
|
||||
LinearGradient(ColorRGBa.PINK, ColorRGBa.WHITE),
|
||||
HalfAngularGradient(ColorRGBa.PINK, ColorRGBa.WHITE)
|
||||
)
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 1000
|
||||
height = 500
|
||||
}
|
||||
program {
|
||||
// Create gradients with initial colors
|
||||
val gradients = listOf(
|
||||
RadialGradient(ColorRGBa.PINK, ColorRGBa.WHITE),
|
||||
AngularGradient(ColorRGBa.PINK, ColorRGBa.WHITE),
|
||||
NPointGradient(Array(4) {
|
||||
ColorRGBa.PINK.shade(it / 3.0)
|
||||
}),
|
||||
LinearGradient(ColorRGBa.PINK, ColorRGBa.WHITE),
|
||||
HalfAngularGradient(ColorRGBa.PINK, ColorRGBa.WHITE)
|
||||
)
|
||||
|
||||
extend {
|
||||
gradients.forEachIndexed { gradientId, gradient ->
|
||||
for (column in 0 until 10) {
|
||||
val color1 = ColorRGBa.PINK.toHSVa().shiftHue(column * 12.0)
|
||||
.shade(0.5).toRGBa()
|
||||
extend {
|
||||
gradients.forEachIndexed { gradientId, gradient ->
|
||||
for (column in 0 until 10) {
|
||||
val color1 = ColorRGBa.PINK.toHSVa().shiftHue(column * 12.0)
|
||||
.shade(0.5).toRGBa()
|
||||
|
||||
val w = width.toDouble() / 10.0
|
||||
val h = height.toDouble() / gradients.size
|
||||
val rect = Rectangle(column * w, gradientId * h, w, h)
|
||||
val w = width.toDouble() / 10.0
|
||||
val h = height.toDouble() / gradients.size
|
||||
val rect = Rectangle(column * w, gradientId * h, w, h)
|
||||
|
||||
val offset = Polar((seconds + column) * 15.0, 0.3).cartesian
|
||||
val offset = Polar((seconds + column) * 15.0, 0.3).cartesian
|
||||
|
||||
drawer.isolated {
|
||||
when (gradient) {
|
||||
is RadialGradient -> {
|
||||
gradient.color1 = color1
|
||||
gradient.exponent = column / 3.0 + 0.3
|
||||
gradient.length = 0.6
|
||||
gradient.offset = offset
|
||||
}
|
||||
is AngularGradient -> {
|
||||
gradient.color1 = color1
|
||||
gradient.exponent = column / 3.0 + 0.3
|
||||
gradient.rotation = (seconds - column) * 10.0
|
||||
gradient.offset = offset
|
||||
}
|
||||
is LinearGradient -> {
|
||||
gradient.color1 = color1
|
||||
gradient.exponent = column / 3.0 + 0.3
|
||||
gradient.rotation = seconds * 10.0
|
||||
}
|
||||
is HalfAngularGradient -> {
|
||||
gradient.color1 = color1
|
||||
gradient.exponent = column / 3.0 + 0.3
|
||||
gradient.rotation = (column - seconds) * 10.0
|
||||
gradient.offset = offset
|
||||
}
|
||||
is NPointGradient -> {
|
||||
// Animate points.
|
||||
// We could also animate colors.
|
||||
gradient.points = Array(gradient.colors.size) {
|
||||
rect.center + Polar(it * 90.0 +
|
||||
drawer.isolated {
|
||||
when (gradient) {
|
||||
is RadialGradient -> {
|
||||
gradient.color1 = color1
|
||||
gradient.exponent = column / 3.0 + 0.3
|
||||
gradient.length = 0.6
|
||||
gradient.offset = offset
|
||||
}
|
||||
|
||||
is AngularGradient -> {
|
||||
gradient.color1 = color1
|
||||
gradient.exponent = column / 3.0 + 0.3
|
||||
gradient.rotation = (seconds - column) * 10.0
|
||||
gradient.offset = offset
|
||||
}
|
||||
|
||||
is LinearGradient -> {
|
||||
gradient.color1 = color1
|
||||
gradient.exponent = column / 3.0 + 0.3
|
||||
gradient.rotation = seconds * 10.0
|
||||
}
|
||||
|
||||
is HalfAngularGradient -> {
|
||||
gradient.color1 = color1
|
||||
gradient.exponent = column / 3.0 + 0.3
|
||||
gradient.rotation = (column - seconds) * 10.0
|
||||
gradient.offset = offset
|
||||
}
|
||||
|
||||
is NPointGradient -> {
|
||||
// Animate points.
|
||||
// We could also animate colors.
|
||||
gradient.points = Array(gradient.colors.size) {
|
||||
rect.center + Polar(
|
||||
it * 90.0 +
|
||||
column * 36 - seconds * 10,
|
||||
40.0).cartesian
|
||||
}
|
||||
40.0
|
||||
).cartesian
|
||||
}
|
||||
}
|
||||
shadeStyle = gradient
|
||||
rectangle(rect)
|
||||
}
|
||||
shadeStyle = gradient
|
||||
rectangle(rect)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,23 +3,21 @@ import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.color.spaces.toOKLABa
|
||||
import org.openrndr.extra.shadestyles.linearGradient
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
extend {
|
||||
drawer.shadeStyle = linearGradient(
|
||||
ColorRGBa.RED.toOKLABa(),
|
||||
ColorRGBa.BLUE.toOKLABa(),
|
||||
)
|
||||
drawer.rectangle(120.0, 40.0, 200.0, 400.0)
|
||||
fun main() = application {
|
||||
program {
|
||||
extend {
|
||||
drawer.shadeStyle = linearGradient(
|
||||
ColorRGBa.RED.toOKLABa(),
|
||||
ColorRGBa.BLUE.toOKLABa(),
|
||||
)
|
||||
drawer.rectangle(120.0, 40.0, 200.0, 400.0)
|
||||
|
||||
drawer.shadeStyle = linearGradient(
|
||||
ColorRGBa.RED,
|
||||
ColorRGBa.BLUE
|
||||
)
|
||||
drawer.shadeStyle = linearGradient(
|
||||
ColorRGBa.RED,
|
||||
ColorRGBa.BLUE
|
||||
)
|
||||
|
||||
drawer.rectangle(120.0+200.0, 40.0, 200.0, 400.0)
|
||||
}
|
||||
drawer.rectangle(120.0 + 200.0, 40.0, 200.0, 400.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,30 +16,28 @@ import kotlin.math.cos
|
||||
* on a static shape (a circle for example) or you can animate a shape
|
||||
* with a static gradient.
|
||||
*/
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val numPoints = 8
|
||||
val gradient = NPointGradient(Array(numPoints) {
|
||||
ColorXSVa(it * 360.0 / numPoints, 1.0, 1.0).toRGBa()
|
||||
})
|
||||
fun main() = application {
|
||||
program {
|
||||
val numPoints = 8
|
||||
val gradient = NPointGradient(Array(numPoints) {
|
||||
ColorXSVa(it * 360.0 / numPoints, 1.0, 1.0).toRGBa()
|
||||
})
|
||||
|
||||
extend {
|
||||
drawer.run {
|
||||
clear(ColorRGBa.WHITE.shade(0.9))
|
||||
val t = PI * 2 * (frameCount % 300) / 300.0
|
||||
val points = Array(numPoints) {
|
||||
val lfo = cos(it * PI / 2 - t)
|
||||
val theta = it * 360.0 / numPoints - 22.5 * lfo
|
||||
val radius = 200 + 170 * lfo
|
||||
bounds.center + Polar(theta, radius).cartesian
|
||||
}
|
||||
gradient.points = points
|
||||
shadeStyle = gradient
|
||||
stroke = ColorRGBa.WHITE
|
||||
strokeWeight = 4.0
|
||||
contour(ShapeContour.fromPoints(points.asList(), true))
|
||||
extend {
|
||||
drawer.run {
|
||||
clear(ColorRGBa.WHITE.shade(0.9))
|
||||
val t = PI * 2 * (frameCount % 300) / 300.0
|
||||
val points = Array(numPoints) {
|
||||
val lfo = cos(it * PI / 2 - t)
|
||||
val theta = it * 360.0 / numPoints - 22.5 * lfo
|
||||
val radius = 200 + 170 * lfo
|
||||
bounds.center + Polar(theta, radius).cartesian
|
||||
}
|
||||
gradient.points = points
|
||||
shadeStyle = gradient
|
||||
stroke = ColorRGBa.WHITE
|
||||
strokeWeight = 4.0
|
||||
contour(ShapeContour.fromPoints(points.asList(), true))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,50 +15,48 @@ import kotlin.math.sin
|
||||
* uniformly between 0.0 and 1.0 and then animated towards one of
|
||||
* the ends over time using pow() and sin(seconds).
|
||||
*/
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val numPoints = 8
|
||||
// Create gradients using two different color spaces
|
||||
val gradients = listOf(
|
||||
NPointLinearGradient(Array(numPoints) {
|
||||
ColorXSVa(it * 360.0 / numPoints, 1.0, 1.0).toRGBa()
|
||||
}),
|
||||
// OKLab is better at maintaining luminosity across the gradient
|
||||
NPointLinearGradientOKLab(Array(numPoints) {
|
||||
ColorXSVa(it * 360.0 / numPoints, 1.0, 1.0).toRGBa()
|
||||
.toOKLABa()
|
||||
})
|
||||
)
|
||||
fun main() = application {
|
||||
program {
|
||||
val numPoints = 8
|
||||
// Create gradients using two different color spaces
|
||||
val gradients = listOf(
|
||||
NPointLinearGradient(Array(numPoints) {
|
||||
ColorXSVa(it * 360.0 / numPoints, 1.0, 1.0).toRGBa()
|
||||
}),
|
||||
// OKLab is better at maintaining luminosity across the gradient
|
||||
NPointLinearGradientOKLab(Array(numPoints) {
|
||||
ColorXSVa(it * 360.0 / numPoints, 1.0, 1.0).toRGBa()
|
||||
.toOKLABa()
|
||||
})
|
||||
)
|
||||
|
||||
extend {
|
||||
// The points should be sorted values between 0.0 and 1.0
|
||||
val distribution = Array(numPoints) {
|
||||
// uniform distribution
|
||||
// (it / (numPoints - 1.0))
|
||||
extend {
|
||||
// The points should be sorted values between 0.0 and 1.0
|
||||
val distribution = Array(numPoints) {
|
||||
// uniform distribution
|
||||
// (it / (numPoints - 1.0))
|
||||
|
||||
// skewed and animated distribution
|
||||
(it / (numPoints - 1.0)).pow(1.0 + 0.5 * sin(seconds))
|
||||
}
|
||||
drawer.run {
|
||||
clear(rgb(0.2))
|
||||
stroke = rgb(0.35)
|
||||
strokeWeight = 8.0
|
||||
// skewed and animated distribution
|
||||
(it / (numPoints - 1.0)).pow(1.0 + 0.5 * sin(seconds))
|
||||
}
|
||||
drawer.run {
|
||||
clear(rgb(0.2))
|
||||
stroke = rgb(0.35)
|
||||
strokeWeight = 8.0
|
||||
|
||||
gradients.forEachIndexed { i, gradient ->
|
||||
shadeStyle = gradient
|
||||
gradient.points = distribution
|
||||
gradients.forEachIndexed { i, gradient ->
|
||||
shadeStyle = gradient
|
||||
gradient.points = distribution
|
||||
|
||||
gradient.rotation = seconds * 10
|
||||
circle(bounds.position(0.34, 0.29 + 0.44 * i), 110.0)
|
||||
gradient.rotation = seconds * 10
|
||||
circle(bounds.position(0.34, 0.29 + 0.44 * i), 110.0)
|
||||
|
||||
gradient.rotation += 90
|
||||
rectangle(
|
||||
Rectangle.fromCenter(
|
||||
bounds.position(0.655, 0.29 + 0.44 * i), 200.0
|
||||
)
|
||||
gradient.rotation += 90
|
||||
rectangle(
|
||||
Rectangle.fromCenter(
|
||||
bounds.position(0.655, 0.29 + 0.44 * i), 200.0
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,34 +6,36 @@ import org.openrndr.shape.Circle
|
||||
import kotlin.random.Random
|
||||
|
||||
/**
|
||||
* Demonstrate using a multi color radial gradient.
|
||||
* Demonstrate using a multicolor radial gradient.
|
||||
* The gradient has 5 colors (first and last ones are transparent).
|
||||
* Any of the properties can be animated, including colors and points.
|
||||
* See DemoNPointLinearGradient01.kt for an example of animated properties.
|
||||
*/
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val gradient = NPointRadialGradient(arrayOf(
|
||||
ColorRGBa.PINK.opacify(0.0),
|
||||
ColorRGBa.PINK, ColorRGBa.WHITE, ColorRGBa.PINK,
|
||||
ColorRGBa.PINK.opacify(0.0)
|
||||
), arrayOf(0.0, 0.4, 0.5, 0.6, 1.0))
|
||||
fun main() = application {
|
||||
program {
|
||||
val gradient = NPointRadialGradient(
|
||||
arrayOf(
|
||||
ColorRGBa.PINK.opacify(0.0),
|
||||
ColorRGBa.PINK, ColorRGBa.WHITE, ColorRGBa.PINK,
|
||||
ColorRGBa.PINK.opacify(0.0)
|
||||
), arrayOf(0.0, 0.4, 0.5, 0.6, 1.0)
|
||||
)
|
||||
|
||||
val circles = List(25) {
|
||||
Circle(Random.nextDouble() * drawer.width,
|
||||
Random.nextDouble() * drawer.height,
|
||||
Random.nextDouble() * 150.0)
|
||||
}
|
||||
val circles = List(25) {
|
||||
Circle(
|
||||
Random.nextDouble() * drawer.width,
|
||||
Random.nextDouble() * drawer.height,
|
||||
Random.nextDouble() * 150.0
|
||||
)
|
||||
}
|
||||
|
||||
extend {
|
||||
drawer.run {
|
||||
clear(rgb(0.2))
|
||||
shadeStyle = gradient
|
||||
fill = ColorRGBa.WHITE
|
||||
stroke = null
|
||||
circles(circles)
|
||||
}
|
||||
extend {
|
||||
drawer.run {
|
||||
clear(rgb(0.2))
|
||||
shadeStyle = gradient
|
||||
fill = ColorRGBa.WHITE
|
||||
stroke = null
|
||||
circles(circles)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,17 +3,15 @@ import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.shadestyles.radialGradient
|
||||
import kotlin.math.cos
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
extend {
|
||||
drawer.shadeStyle = radialGradient(
|
||||
ColorRGBa.PINK,
|
||||
ColorRGBa.PINK.toHSVa().shiftHue(180.0).shade(0.5).toRGBa(),
|
||||
exponent = cos(seconds)*0.5+0.5
|
||||
)
|
||||
drawer.rectangle(120.0, 40.0, 400.0, 400.0)
|
||||
}
|
||||
fun main() = application {
|
||||
program {
|
||||
extend {
|
||||
drawer.shadeStyle = radialGradient(
|
||||
ColorRGBa.PINK,
|
||||
ColorRGBa.PINK.toHSVa().shiftHue(180.0).shade(0.5).toRGBa(),
|
||||
exponent = cos(seconds) * 0.5 + 0.5
|
||||
)
|
||||
drawer.rectangle(120.0, 40.0, 400.0, 400.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,28 +8,26 @@ import org.openrndr.shape.Circle
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
var contour = Circle(drawer.bounds.center, 300.0).contour
|
||||
contour = adjustContour(contour) {
|
||||
selectVertex(0)
|
||||
vertex.moveBy(Vector2(cos(seconds) * 40.0, sin(seconds * 0.43) * 40.0))
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
var contour = Circle(drawer.bounds.center, 300.0).contour
|
||||
contour = adjustContour(contour) {
|
||||
selectVertex(0)
|
||||
vertex.moveBy(Vector2(cos(seconds) * 40.0, sin(seconds * 0.43) * 40.0))
|
||||
|
||||
selectVertex(2)
|
||||
vertex.rotate(seconds * 45.0)
|
||||
selectVertex(2)
|
||||
vertex.rotate(seconds * 45.0)
|
||||
|
||||
selectVertex(1)
|
||||
vertex.scale(cos(seconds*0.943)*2.0)
|
||||
}
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.contour(contour)
|
||||
selectVertex(1)
|
||||
vertex.scale(cos(seconds * 0.943) * 2.0)
|
||||
}
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.contour(contour)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,27 +8,25 @@ import org.openrndr.shape.Circle
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
var contour = Circle(drawer.bounds.center, 300.0).contour
|
||||
contour = adjustContour(contour) {
|
||||
selectVertex(0)
|
||||
vertex.remove()
|
||||
selectVertex(0)
|
||||
vertex.moveBy(Vector2(cos(seconds) * 40.0, sin(seconds * 0.43) * 40.0))
|
||||
vertex.scale(cos(seconds*2.0)*2.0)
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
var contour = Circle(drawer.bounds.center, 300.0).contour
|
||||
contour = adjustContour(contour) {
|
||||
selectVertex(0)
|
||||
vertex.remove()
|
||||
selectVertex(0)
|
||||
vertex.moveBy(Vector2(cos(seconds) * 40.0, sin(seconds * 0.43) * 40.0))
|
||||
vertex.scale(cos(seconds * 2.0) * 2.0)
|
||||
|
||||
|
||||
}
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.contour(contour)
|
||||
}
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.contour(contour)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,37 +7,35 @@ import org.openrndr.math.Vector2
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
var contour = drawer.bounds.scaledBy(0.5, 0.5, 0.5).contour
|
||||
contour = adjustContour(contour) {
|
||||
for (i in 0 until 4) {
|
||||
selectEdge(i)
|
||||
edge.toCubic()
|
||||
}
|
||||
selectEdge(0)
|
||||
edge.scale(0.5, 0.5)
|
||||
edge.rotate(cos(seconds*0.5)*30.0)
|
||||
selectEdge(1)
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
var contour = drawer.bounds.scaledBy(0.5, 0.5, 0.5).contour
|
||||
contour = adjustContour(contour) {
|
||||
for (i in 0 until 4) {
|
||||
selectEdge(i)
|
||||
edge.toCubic()
|
||||
edge.splitAt(0.5)
|
||||
edge.moveBy(Vector2(cos(seconds*10.0) * 40.0, 0.0))
|
||||
//edge.next?.select()
|
||||
selectEdge(3)
|
||||
|
||||
edge.moveBy(Vector2(0.0, sin(seconds*10.0) * 40.0))
|
||||
|
||||
|
||||
}
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.contour(contour)
|
||||
selectEdge(0)
|
||||
edge.scale(0.5, 0.5)
|
||||
edge.rotate(cos(seconds * 0.5) * 30.0)
|
||||
selectEdge(1)
|
||||
edge.toCubic()
|
||||
edge.splitAt(0.5)
|
||||
edge.moveBy(Vector2(cos(seconds * 10.0) * 40.0, 0.0))
|
||||
//edge.next?.select()
|
||||
selectEdge(3)
|
||||
|
||||
edge.moveBy(Vector2(0.0, sin(seconds * 10.0) * 40.0))
|
||||
|
||||
|
||||
}
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.contour(contour)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,26 +6,24 @@ import org.openrndr.extra.shapes.adjust.adjustContour
|
||||
import org.openrndr.shape.Circle
|
||||
import kotlin.math.cos
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
var contour = if (seconds.mod(2.0) < 1.0) {
|
||||
drawer.bounds.scaledBy(0.5, 0.5, 0.5).contour
|
||||
} else {
|
||||
Circle(drawer.bounds.center, 300.0).contour
|
||||
}
|
||||
contour = adjustContour(contour) {
|
||||
selectEdge(0)
|
||||
edge.replaceWith(cos(seconds) * 0.5 + 0.5)
|
||||
}
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.contour(contour)
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
var contour = if (seconds.mod(2.0) < 1.0) {
|
||||
drawer.bounds.scaledBy(0.5, 0.5, 0.5).contour
|
||||
} else {
|
||||
Circle(drawer.bounds.center, 300.0).contour
|
||||
}
|
||||
contour = adjustContour(contour) {
|
||||
selectEdge(0)
|
||||
edge.replaceWith(cos(seconds) * 0.5 + 0.5)
|
||||
}
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.contour(contour)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,31 +6,29 @@ import org.openrndr.extra.shapes.adjust.adjustContour
|
||||
import org.openrndr.shape.Circle
|
||||
import kotlin.math.cos
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
var contour =
|
||||
Circle(drawer.bounds.center, 300.0).contour
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
var contour =
|
||||
Circle(drawer.bounds.center, 300.0).contour
|
||||
|
||||
contour = adjustContour(contour) {
|
||||
selectEdges(0, 1, 2, 3)
|
||||
edges.forEachIndexed { index, it ->
|
||||
if (index == seconds.mod(4.0).toInt()) {
|
||||
it.replaceWith(0.5)
|
||||
} else {
|
||||
val v = cos(seconds) * 0.15 + 0.25
|
||||
it.sub(0.5 - v, 0.5 + v)
|
||||
}
|
||||
contour = adjustContour(contour) {
|
||||
selectEdges(0, 1, 2, 3)
|
||||
edges.forEachIndexed { index, it ->
|
||||
if (index == seconds.mod(4.0).toInt()) {
|
||||
it.replaceWith(0.5)
|
||||
} else {
|
||||
val v = cos(seconds) * 0.15 + 0.25
|
||||
it.sub(0.5 - v, 0.5 + v)
|
||||
}
|
||||
}
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.contour(contour)
|
||||
}
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.contour(contour)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,38 +6,36 @@ import org.openrndr.extra.shapes.adjust.adjustContour
|
||||
import org.openrndr.shape.Circle
|
||||
import kotlin.math.cos
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
var contour =
|
||||
Circle(drawer.bounds.center, 300.0).contour
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
var contour =
|
||||
Circle(drawer.bounds.center, 300.0).contour
|
||||
|
||||
contour = adjustContour(contour) {
|
||||
parameters.clearSelectedVertices = true
|
||||
parameters.selectInsertedVertices = true
|
||||
contour = adjustContour(contour) {
|
||||
parameters.clearSelectedVertices = true
|
||||
parameters.selectInsertedVertices = true
|
||||
|
||||
|
||||
for (i in 0 until 4) {
|
||||
val splitT = cos(seconds + i * Math.PI*0.5)*0.2+0.5
|
||||
selectEdges { it -> true }
|
||||
for (e in edges) {
|
||||
e.splitAt(splitT)
|
||||
}
|
||||
// as a resut of the clearSelectedVertices and selectInsertedVertices settings
|
||||
// the vertex selection is set to the newly inserted vertices
|
||||
for ((index, v) in vertices.withIndex()) {
|
||||
v.scale(cos(seconds + i + index) * 0.5 * (1.0 / (1.0 + i)) + 1.0, drawer.bounds.center)
|
||||
}
|
||||
for (i in 0 until 4) {
|
||||
val splitT = cos(seconds + i * Math.PI * 0.5) * 0.2 + 0.5
|
||||
selectEdges { it -> true }
|
||||
for (e in edges) {
|
||||
e.splitAt(splitT)
|
||||
}
|
||||
// as a resut of the clearSelectedVertices and selectInsertedVertices settings
|
||||
// the vertex selection is set to the newly inserted vertices
|
||||
for ((index, v) in vertices.withIndex()) {
|
||||
v.scale(cos(seconds + i + index) * 0.5 * (1.0 / (1.0 + i)) + 1.0, drawer.bounds.center)
|
||||
}
|
||||
}
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.contour(contour)
|
||||
}
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.contour(contour)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,36 +7,34 @@ import org.openrndr.math.Vector2
|
||||
import org.openrndr.shape.contour
|
||||
import kotlin.math.cos
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
var contour = contour {
|
||||
moveTo(drawer.bounds.center - Vector2(300.0, 0.0))
|
||||
lineTo(drawer.bounds.center + Vector2(300.0, 0.0))
|
||||
}
|
||||
|
||||
contour = adjustContour(contour) {
|
||||
selectEdge(0)
|
||||
edge.splitIn(128)
|
||||
val tr = cos(seconds) * 0.5 + 0.5
|
||||
|
||||
selectVertices { i, v -> v.t >= tr }
|
||||
val anchor = contour.position(tr)
|
||||
|
||||
for (v in vertices) {
|
||||
v.rotate((v.t - tr) * 2000.0, anchor)
|
||||
v.scale(0.05, anchor)
|
||||
}
|
||||
}
|
||||
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.contour(contour)
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
var contour = contour {
|
||||
moveTo(drawer.bounds.center - Vector2(300.0, 0.0))
|
||||
lineTo(drawer.bounds.center + Vector2(300.0, 0.0))
|
||||
}
|
||||
|
||||
contour = adjustContour(contour) {
|
||||
selectEdge(0)
|
||||
edge.splitIn(128)
|
||||
val tr = cos(seconds) * 0.5 + 0.5
|
||||
|
||||
selectVertices { i, v -> v.t >= tr }
|
||||
val anchor = contour.position(tr)
|
||||
|
||||
for (v in vertices) {
|
||||
v.rotate((v.t - tr) * 2000.0, anchor)
|
||||
v.scale(0.05, anchor)
|
||||
}
|
||||
}
|
||||
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.contour(contour)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
//package adjust
|
||||
package adjust
|
||||
|
||||
import org.openrndr.application
|
||||
import org.openrndr.color.ColorRGBa
|
||||
@@ -6,46 +6,44 @@ import org.openrndr.extra.shapes.adjust.adjustContour
|
||||
import org.openrndr.math.Vector2
|
||||
import org.openrndr.shape.contour
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
var contour = contour {
|
||||
moveTo(drawer.bounds.position(0.5, 0.1) - Vector2(300.0, 0.0))
|
||||
lineTo(drawer.bounds.position(0.5, 0.1) + Vector2(300.0, 0.0))
|
||||
}
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
var contour = contour {
|
||||
moveTo(drawer.bounds.position(0.5, 0.1) - Vector2(300.0, 0.0))
|
||||
lineTo(drawer.bounds.position(0.5, 0.1) + Vector2(300.0, 0.0))
|
||||
}
|
||||
|
||||
contour = adjustContour(contour) {
|
||||
selectVertex(0)
|
||||
vertex.moveControlOutBy(Vector2(0.0, 100.0))
|
||||
contour = adjustContour(contour) {
|
||||
selectVertex(0)
|
||||
vertex.moveControlOutBy(Vector2(0.0, 100.0))
|
||||
|
||||
selectVertex(1)
|
||||
vertex.moveControlInBy(Vector2(0.0, -100.0))
|
||||
|
||||
}
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.contour(contour)
|
||||
|
||||
|
||||
contour = contour {
|
||||
moveTo(drawer.bounds.position(0.5, 0.2) - Vector2(300.0, 0.0))
|
||||
lineTo(drawer.bounds.position(0.5, 0.2) + Vector2(300.0, 0.0))
|
||||
}
|
||||
|
||||
contour = adjustContour(contour) {
|
||||
selectEdge(0)
|
||||
edge.moveControl0By(Vector2(0.0, 100.0))
|
||||
edge.moveControl1By(Vector2(0.0, -100.0))
|
||||
|
||||
}
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.contour(contour)
|
||||
selectVertex(1)
|
||||
vertex.moveControlInBy(Vector2(0.0, -100.0))
|
||||
|
||||
}
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.contour(contour)
|
||||
|
||||
|
||||
contour = contour {
|
||||
moveTo(drawer.bounds.position(0.5, 0.2) - Vector2(300.0, 0.0))
|
||||
lineTo(drawer.bounds.position(0.5, 0.2) + Vector2(300.0, 0.0))
|
||||
}
|
||||
|
||||
contour = adjustContour(contour) {
|
||||
selectEdge(0)
|
||||
edge.moveControl0By(Vector2(0.0, 100.0))
|
||||
edge.moveControl1By(Vector2(0.0, -100.0))
|
||||
|
||||
}
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.contour(contour)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,51 +9,49 @@ import org.openrndr.extra.shapes.tunni.tunniLine
|
||||
import org.openrndr.extra.shapes.tunni.tunniPoint
|
||||
import kotlin.math.sqrt
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.WHITE)
|
||||
var contour = drawer.bounds.offsetEdges(-200.0).contour
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.WHITE)
|
||||
var contour = drawer.bounds.offsetEdges(-200.0).contour
|
||||
|
||||
drawer.fill = null
|
||||
drawer.fill = null
|
||||
|
||||
contour = adjustContour(contour) {
|
||||
selectVertices(0, 1)
|
||||
for (v in vertices) {
|
||||
v.averageTangents()
|
||||
v.scale(sqrt(2.0))
|
||||
v.rotate(45.0)
|
||||
}
|
||||
|
||||
selectVertices(2)
|
||||
for (v in vertices) {
|
||||
v.switchTangents()
|
||||
}
|
||||
contour = adjustContour(contour) {
|
||||
selectVertices(0, 1)
|
||||
for (v in vertices) {
|
||||
v.averageTangents()
|
||||
v.scale(sqrt(2.0))
|
||||
v.rotate(45.0)
|
||||
}
|
||||
drawer.stroke = ColorRGBa.BLACK
|
||||
drawer.contour(contour)
|
||||
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
|
||||
for (s in contour.segments) {
|
||||
drawer.lineSegment(s.start, s.cubic.control[0])
|
||||
drawer.lineSegment(s.end, s.cubic.control[1])
|
||||
selectVertices(2)
|
||||
for (v in vertices) {
|
||||
v.switchTangents()
|
||||
}
|
||||
drawer.fill = ColorRGBa.BLACK
|
||||
drawer.stroke = null
|
||||
drawer.circles(contour.segments.map { it.start }, 5.0)
|
||||
}
|
||||
drawer.stroke = ColorRGBa.BLACK
|
||||
drawer.contour(contour)
|
||||
|
||||
drawer.stroke = ColorRGBa.GRAY
|
||||
for (s in contour.segments) {
|
||||
drawer.lineSegment(s.tunniLine)
|
||||
drawer.fill = ColorRGBa.CYAN
|
||||
drawer.circle(s.tunniPoint, 5.0)
|
||||
}
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
|
||||
for (s in contour.segments) {
|
||||
drawer.lineSegment(s.start, s.cubic.control[0])
|
||||
drawer.lineSegment(s.end, s.cubic.control[1])
|
||||
}
|
||||
drawer.fill = ColorRGBa.BLACK
|
||||
drawer.stroke = null
|
||||
drawer.circles(contour.segments.map { it.start }, 5.0)
|
||||
|
||||
drawer.stroke = ColorRGBa.GRAY
|
||||
for (s in contour.segments) {
|
||||
drawer.lineSegment(s.tunniLine)
|
||||
drawer.fill = ColorRGBa.CYAN
|
||||
drawer.circle(s.tunniPoint, 5.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,90 +12,88 @@ import org.openrndr.math.Vector2
|
||||
import org.openrndr.shape.Segment2D
|
||||
import kotlin.math.cos
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
|
||||
var res = drawer.bounds.offsetEdges(-200.0).contour
|
||||
var selectedSegments = emptyList<Segment2D>()
|
||||
var selectedPoints = emptyList<Vector2>()
|
||||
var res = drawer.bounds.offsetEdges(-200.0).contour
|
||||
var selectedSegments = emptyList<Segment2D>()
|
||||
var selectedPoints = emptyList<Vector2>()
|
||||
|
||||
val contourSeq = adjustContourSequence(res) {
|
||||
val contourSeq = adjustContourSequence(res) {
|
||||
|
||||
sequence {
|
||||
for (i in 0 until 1000) {
|
||||
selectEdges()
|
||||
selectVertices((i*7).mod(4))
|
||||
for (v in vertices) {
|
||||
for (j in 0 until 30) {
|
||||
v.rotate(45.0/30.0)
|
||||
yield(status)
|
||||
}
|
||||
}
|
||||
|
||||
selectVertices((i*3).mod(4))
|
||||
for (v in vertices) {
|
||||
yield(status)
|
||||
|
||||
}
|
||||
|
||||
|
||||
selectVertices()
|
||||
selectEdges(i.mod(4))
|
||||
sequence {
|
||||
for (i in 0 until 1000) {
|
||||
selectEdges()
|
||||
selectVertices((i * 7).mod(4))
|
||||
for (v in vertices) {
|
||||
for (j in 0 until 30) {
|
||||
for (e in edges) {
|
||||
e.withTunniLine(e.tunniLine.position(0.5) + e.tunniLine.normal * cos(i.toDouble() + e.segmentIndex()) * 50.0/30.0)
|
||||
yield(status)
|
||||
}
|
||||
v.rotate(45.0 / 30.0)
|
||||
yield(status)
|
||||
}
|
||||
}
|
||||
|
||||
selectVertices((i * 3).mod(4))
|
||||
for (v in vertices) {
|
||||
yield(status)
|
||||
|
||||
}
|
||||
|
||||
|
||||
selectVertices()
|
||||
selectEdges(i.mod(4))
|
||||
for (j in 0 until 30) {
|
||||
for (e in edges) {
|
||||
e.withTunniLine(e.tunniLine.position(0.5) + e.tunniLine.normal * cos(i.toDouble() + e.segmentIndex()) * 50.0 / 30.0)
|
||||
yield(status)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
launch {
|
||||
for (i in contourSeq) {
|
||||
res = i.contour
|
||||
selectedPoints = i.selectedPoints
|
||||
selectedSegments = i.selectedSegments
|
||||
yield()
|
||||
}
|
||||
launch {
|
||||
for (i in contourSeq) {
|
||||
res = i.contour
|
||||
selectedPoints = i.selectedPoints
|
||||
selectedSegments = i.selectedSegments
|
||||
yield()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.WHITE)
|
||||
drawer.stroke = ColorRGBa.BLACK
|
||||
drawer.contour(res)
|
||||
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
|
||||
for (s in res.segments) {
|
||||
drawer.lineSegment(s.start, s.cubic.control[0])
|
||||
drawer.lineSegment(s.end, s.cubic.control[1])
|
||||
}
|
||||
drawer.fill = ColorRGBa.BLACK
|
||||
drawer.stroke = null
|
||||
drawer.circles(res.segments.map { it.start }, 5.0)
|
||||
|
||||
drawer.stroke = ColorRGBa.GRAY
|
||||
for (s in res.segments) {
|
||||
drawer.lineSegment(s.tunniLine)
|
||||
drawer.fill = ColorRGBa.CYAN
|
||||
drawer.circle(s.tunniPoint, 5.0)
|
||||
}
|
||||
|
||||
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.WHITE)
|
||||
drawer.stroke = ColorRGBa.BLACK
|
||||
drawer.contour(res)
|
||||
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
|
||||
for (s in res.segments) {
|
||||
drawer.lineSegment(s.start, s.cubic.control[0])
|
||||
drawer.lineSegment(s.end, s.cubic.control[1])
|
||||
}
|
||||
drawer.fill = ColorRGBa.BLACK
|
||||
drawer.stroke = null
|
||||
drawer.circles(res.segments.map { it.start }, 5.0)
|
||||
|
||||
drawer.stroke = ColorRGBa.GRAY
|
||||
for (s in res.segments) {
|
||||
drawer.lineSegment(s.tunniLine)
|
||||
drawer.fill = ColorRGBa.CYAN
|
||||
drawer.circle(s.tunniPoint, 5.0)
|
||||
}
|
||||
|
||||
drawer.stroke = ColorRGBa.MAGENTA
|
||||
drawer.strokeWeight = 3.0
|
||||
for (s in selectedSegments) {
|
||||
drawer.segment(s)
|
||||
}
|
||||
for (p in selectedPoints) {
|
||||
drawer.circle(p, 5.0)
|
||||
}
|
||||
drawer.stroke = ColorRGBa.MAGENTA
|
||||
drawer.strokeWeight = 3.0
|
||||
for (s in selectedSegments) {
|
||||
drawer.segment(s)
|
||||
}
|
||||
for (p in selectedPoints) {
|
||||
drawer.circle(p, 5.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,33 +12,34 @@ import org.openrndr.shape.Circle
|
||||
import kotlin.math.sqrt
|
||||
import kotlin.random.Random
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
val circles = listOf(
|
||||
Circle(drawer.bounds.center -Vector2(50.0, 0.0), 50.0),
|
||||
Circle(drawer.bounds.center + Vector2(50.0, 0.0), 50.0),
|
||||
Circle(drawer.bounds.center + Vector2(0.0, 50.0), 50.0),
|
||||
Circle(drawer.bounds.center - Vector2(0.0, 50.0), 50.0),
|
||||
Circle(drawer.bounds.center -Vector2(50.0, 0.0), sqrt(50.0*50.0+50.0*50.0)-49.9),
|
||||
Circle(drawer.bounds.center +Vector2(50.0, 0.0), sqrt(50.0*50.0+50.0*50.0)-49.9),
|
||||
Circle(drawer.bounds.center -Vector2(0.0, 50.0), sqrt(50.0*50.0+50.0*50.0)-49.9),
|
||||
Circle(drawer.bounds.center +Vector2(0.0, 50.0), sqrt(50.0*50.0+50.0*50.0)-49.9),
|
||||
).shuffled()
|
||||
fun main() = application {
|
||||
program {
|
||||
val circles = listOf(
|
||||
Circle(drawer.bounds.center - Vector2(50.0, 0.0), 50.0),
|
||||
Circle(drawer.bounds.center + Vector2(50.0, 0.0), 50.0),
|
||||
Circle(drawer.bounds.center + Vector2(0.0, 50.0), 50.0),
|
||||
Circle(drawer.bounds.center - Vector2(0.0, 50.0), 50.0),
|
||||
Circle(drawer.bounds.center - Vector2(50.0, 0.0), sqrt(50.0 * 50.0 + 50.0 * 50.0) - 49.9),
|
||||
Circle(drawer.bounds.center + Vector2(50.0, 0.0), sqrt(50.0 * 50.0 + 50.0 * 50.0) - 49.9),
|
||||
Circle(drawer.bounds.center - Vector2(0.0, 50.0), sqrt(50.0 * 50.0 + 50.0 * 50.0) - 49.9),
|
||||
Circle(drawer.bounds.center + Vector2(0.0, 50.0), sqrt(50.0 * 50.0 + 50.0 * 50.0) - 49.9),
|
||||
).shuffled()
|
||||
|
||||
val arr = Arrangement(circles)
|
||||
val arr = Arrangement(circles)
|
||||
|
||||
extend {
|
||||
val r = Random(100)
|
||||
drawer.stroke = ColorRGBa.WHITE
|
||||
for (f in arr.boundedFaces) {
|
||||
drawer.fill =
|
||||
extend {
|
||||
val r = Random(100)
|
||||
drawer.stroke = ColorRGBa.WHITE
|
||||
for (f in arr.boundedFaces) {
|
||||
drawer.fill =
|
||||
|
||||
rgb(Double.uniform(0.0, 1.0, r), Double.uniform(0.0, 1.0, r), Double.uniform(0.0, 1.0, r)).saturate<OKHSV>(0.25)
|
||||
drawer.contour(f.contour)
|
||||
}
|
||||
rgb(
|
||||
Double.uniform(0.0, 1.0, r),
|
||||
Double.uniform(0.0, 1.0, r),
|
||||
Double.uniform(0.0, 1.0, r)
|
||||
).saturate<OKHSV>(0.25)
|
||||
drawer.contour(f.contour)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,41 +15,39 @@ import org.openrndr.shape.ShapeContour
|
||||
* The created contours are horizontal and vertical in "bezier-patch space" but
|
||||
* are rendered deformed following the shape of the bezier patch.
|
||||
*/
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
// helper to get screen locations using normalized uv values
|
||||
fun pos(u: Double, v: Double) = drawer.bounds.position(u, v)
|
||||
val c0 = LineSegment(pos(0.1, 0.1), pos(0.9, 0.1))
|
||||
val c1 = LineSegment(pos(0.4, 0.3), pos(0.6, 0.4))
|
||||
val c2 = LineSegment(pos(0.4, 0.7), pos(0.6, 0.6))
|
||||
val c3 = LineSegment(pos(0.1, 0.9), pos(0.9, 0.9))
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
// helper to get screen locations using normalized uv values
|
||||
fun pos(u: Double, v: Double) = drawer.bounds.position(u, v)
|
||||
val c0 = LineSegment(pos(0.1, 0.1), pos(0.9, 0.1))
|
||||
val c1 = LineSegment(pos(0.4, 0.3), pos(0.6, 0.4))
|
||||
val c2 = LineSegment(pos(0.4, 0.7), pos(0.6, 0.6))
|
||||
val c3 = LineSegment(pos(0.1, 0.9), pos(0.9, 0.9))
|
||||
|
||||
val bp = bezierPatch(c0.segment, c1.segment, c2.segment, c3.segment)
|
||||
val bpSub = bp.sub(0.1, 0.1, 0.6,0.6)
|
||||
val bp = bezierPatch(c0.segment, c1.segment, c2.segment, c3.segment)
|
||||
val bpSub = bp.sub(0.1, 0.1, 0.6, 0.6)
|
||||
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
|
||||
// Show the line segments that form the bezier patch
|
||||
drawer.stroke = ColorRGBa.YELLOW
|
||||
drawer.strokeWeight = 5.0
|
||||
drawer.lineSegments(listOf(c0, c1, c2, c3))
|
||||
// Show the line segments that form the bezier patch
|
||||
drawer.stroke = ColorRGBa.YELLOW
|
||||
drawer.strokeWeight = 5.0
|
||||
drawer.lineSegments(listOf(c0, c1, c2, c3))
|
||||
|
||||
drawer.strokeWeight = 1.0
|
||||
for (i in 0..50) {
|
||||
drawer.stroke = ColorRGBa.BLACK
|
||||
drawer.contour(bp.horizontal(i / 50.0))
|
||||
drawer.contour(bp.vertical(i / 50.0))
|
||||
drawer.strokeWeight = 1.0
|
||||
for (i in 0..50) {
|
||||
drawer.stroke = ColorRGBa.BLACK
|
||||
drawer.contour(bp.horizontal(i / 50.0))
|
||||
drawer.contour(bp.vertical(i / 50.0))
|
||||
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.contour(bpSub.horizontal(i / 50.0))
|
||||
drawer.contour(bpSub.vertical(i / 50.0))
|
||||
}
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.contour(bpSub.horizontal(i / 50.0))
|
||||
drawer.contour(bpSub.vertical(i / 50.0))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,24 +15,22 @@ import org.openrndr.shape.ShapeContour
|
||||
* but one can manually create any other 4-segment closed contour
|
||||
* to use in bezier patches.
|
||||
*/
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
val c = Circle(width / 2.0, height / 2.0, 350.0).contour
|
||||
val bp = bezierPatch(c)
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
val c = Circle(width / 2.0, height / 2.0, 350.0).contour
|
||||
val bp = bezierPatch(c)
|
||||
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
drawer.stroke = ColorRGBa.BLACK
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
drawer.stroke = ColorRGBa.BLACK
|
||||
|
||||
for (i in 0..10) {
|
||||
drawer.contour(bp.horizontal(i / 10.0))
|
||||
drawer.contour(bp.vertical(i / 10.0))
|
||||
}
|
||||
for (i in 0..10) {
|
||||
drawer.contour(bp.horizontal(i / 10.0))
|
||||
drawer.contour(bp.vertical(i / 10.0))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,42 +15,40 @@ import org.openrndr.shape.ShapeContour
|
||||
* In this case the contours are regular stars and the bezier patch
|
||||
* is created using a circular contour with the required 4 segments.
|
||||
*/
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
val bp = bezierPatch(
|
||||
Circle(width / 2.0, height / 2.0, 350.0).contour
|
||||
)
|
||||
val star = regularStarRounded(
|
||||
7, 30.0, 40.0,
|
||||
0.5, 0.5
|
||||
)
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
val bp = bezierPatch(
|
||||
Circle(width / 2.0, height / 2.0, 350.0).contour
|
||||
)
|
||||
val star = regularStarRounded(
|
||||
7, 30.0, 40.0,
|
||||
0.5, 0.5
|
||||
)
|
||||
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
|
||||
// draw grid
|
||||
for (i in 0..50) {
|
||||
drawer.stroke = ColorRGBa.BLACK
|
||||
drawer.contour(bp.horizontal(i / 50.0))
|
||||
drawer.contour(bp.vertical(i / 50.0))
|
||||
}
|
||||
// draw grid
|
||||
for (i in 0..50) {
|
||||
drawer.stroke = ColorRGBa.BLACK
|
||||
drawer.contour(bp.horizontal(i / 50.0))
|
||||
drawer.contour(bp.vertical(i / 50.0))
|
||||
}
|
||||
|
||||
// draw stars
|
||||
drawer.fill = ColorRGBa.PINK
|
||||
for (j in 1 until 10) {
|
||||
for (i in 1 until 10) {
|
||||
val starMoved = star.transform(
|
||||
transform {
|
||||
translate(j * width / 10.0, i * height / 10.0)
|
||||
}
|
||||
)
|
||||
drawer.contour(bp.distort(starMoved, drawer.bounds))
|
||||
}
|
||||
// draw stars
|
||||
drawer.fill = ColorRGBa.PINK
|
||||
for (j in 1 until 10) {
|
||||
for (i in 1 until 10) {
|
||||
val starMoved = star.transform(
|
||||
transform {
|
||||
translate(j * width / 10.0, i * height / 10.0)
|
||||
}
|
||||
)
|
||||
drawer.contour(bp.distort(starMoved, drawer.bounds))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,33 +12,31 @@ import org.openrndr.shape.Circle
|
||||
* You can think of bezierPatch.position() as requesting points
|
||||
* in a wavy flag (the bezier patch) using normalized uv coordinates.
|
||||
*/
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
val bp = bezierPatch(
|
||||
Circle(drawer.bounds.center, 350.0).contour
|
||||
//Rectangle.fromCenter(drawer.bounds.center, 550.0).contour
|
||||
)
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
val bp = bezierPatch(
|
||||
Circle(drawer.bounds.center, 350.0).contour
|
||||
//Rectangle.fromCenter(drawer.bounds.center, 550.0).contour
|
||||
)
|
||||
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
drawer.stroke = ColorRGBa.BLACK
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
drawer.stroke = ColorRGBa.BLACK
|
||||
|
||||
for (j in 1 until 50 step 2) {
|
||||
for (i in 1 until 50 step 2) {
|
||||
val u = i / 50.0
|
||||
val v = j / 50.0
|
||||
val pos = bp.position(u, v)
|
||||
val grad = bp.gradient(u, v).normalized * 10.0
|
||||
val perpendicular = grad.perpendicular()
|
||||
drawer.lineSegment(pos - grad, pos + grad)
|
||||
drawer.lineSegment(pos - perpendicular, pos + perpendicular)
|
||||
//drawer.circle(pos + grad, 3.0)
|
||||
}
|
||||
for (j in 1 until 50 step 2) {
|
||||
for (i in 1 until 50 step 2) {
|
||||
val u = i / 50.0
|
||||
val v = j / 50.0
|
||||
val pos = bp.position(u, v)
|
||||
val grad = bp.gradient(u, v).normalized * 10.0
|
||||
val perpendicular = grad.perpendicular()
|
||||
drawer.lineSegment(pos - grad, pos + grad)
|
||||
drawer.lineSegment(pos - perpendicular, pos + perpendicular)
|
||||
//drawer.circle(pos + grad, 3.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package bezierpatch
|
||||
import org.openrndr.WindowMultisample
|
||||
import org.openrndr.application
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.shapes.bezierpatches.bezierPatch
|
||||
import org.openrndr.extra.camera.Orbital
|
||||
import org.openrndr.extra.shapes.bezierpatches.bezierPatch
|
||||
import org.openrndr.math.Vector3
|
||||
import org.openrndr.shape.Segment3D
|
||||
|
||||
@@ -19,56 +19,54 @@ import org.openrndr.shape.Segment3D
|
||||
* The created contours are horizontal and vertical in "bezier-patch space" but
|
||||
* are rendered deformed following the shape of the bezier patch.
|
||||
*/
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
multisample = WindowMultisample.SampleCount(8)
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
multisample = WindowMultisample.SampleCount(8)
|
||||
}
|
||||
program {
|
||||
val c0 = Segment3D(Vector3(-5.0, 0.0, -9.0), Vector3(5.0, 0.0, -9.0))
|
||||
val c1 = Segment3D(Vector3(-5.0, -5.0, -3.0), Vector3(5.0, -5.0, -3.0))
|
||||
val c2 = Segment3D(Vector3(-5.0, 5.0, 3.0), Vector3(5.0, 5.0, 3.0))
|
||||
val c3 = Segment3D(Vector3(-5.0, 0.0, 9.0), Vector3(5.0, 0.0, 9.0))
|
||||
|
||||
val col = listOf(ColorRGBa.PINK, ColorRGBa.RED, ColorRGBa.BLUE, ColorRGBa.PINK)
|
||||
val cols = listOf(col, col, col, col)
|
||||
val bp = bezierPatch(c0, c1, c2, c3).withColors(cols)
|
||||
val bpSub = bp.sub(0.1, 0.1, 0.6, 0.6)
|
||||
|
||||
val cam = Orbital()
|
||||
extend(cam) {
|
||||
eye = Vector3(x = 9.9, y = 12.8, z = 6.9)
|
||||
lookAt = Vector3(x = 1.6, y = -1.9, z = 1.2)
|
||||
}
|
||||
program {
|
||||
val c0 = Segment3D(Vector3(-5.0, 0.0, -9.0), Vector3(5.0, 0.0, -9.0))
|
||||
val c1 = Segment3D(Vector3(-5.0, -5.0, -3.0), Vector3(5.0, -5.0, -3.0))
|
||||
val c2 = Segment3D(Vector3(-5.0, 5.0, 3.0), Vector3(5.0, 5.0, 3.0))
|
||||
val c3 = Segment3D(Vector3(-5.0, 0.0, 9.0), Vector3(5.0, 0.0, 9.0))
|
||||
|
||||
val col = listOf(ColorRGBa.PINK, ColorRGBa.RED, ColorRGBa.BLUE, ColorRGBa.PINK)
|
||||
val cols = listOf(col, col, col, col)
|
||||
val bp = bezierPatch(c0, c1, c2, c3).withColors(cols)
|
||||
val bpSub = bp.sub(0.1, 0.1, 0.6, 0.6)
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
|
||||
val cam = Orbital()
|
||||
extend(cam){
|
||||
eye = Vector3(x=9.9, y=12.8, z=6.9)
|
||||
lookAt = Vector3(x=1.6, y=-1.9, z=1.2)
|
||||
drawer.translate(-5.0, 0.0, 0.0)
|
||||
// Show the segments that form the bezier patch
|
||||
drawer.stroke = ColorRGBa.YELLOW
|
||||
drawer.strokeWeight = 50.0
|
||||
drawer.segments(listOf(c0, c1, c2, c3))
|
||||
|
||||
// Show the grid
|
||||
drawer.strokeWeight = 1.0
|
||||
val n = 10
|
||||
for (i in 0..n) {
|
||||
drawer.stroke = ColorRGBa.BLACK
|
||||
drawer.lineStrip(bp.horizontal(i / n.toDouble()).adaptivePositions(0.01))
|
||||
drawer.lineStrip(bp.vertical(i / n.toDouble()).adaptivePositions(0.01))
|
||||
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.lineStrip(bpSub.horizontal(i / n.toDouble()).adaptivePositions(0.01))
|
||||
drawer.lineStrip(bpSub.vertical(i / n.toDouble()).adaptivePositions(0.01))
|
||||
}
|
||||
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
|
||||
drawer.translate(-5.0, 0.0, 0.0)
|
||||
// Show the segments that form the bezier patch
|
||||
drawer.stroke = ColorRGBa.YELLOW
|
||||
drawer.strokeWeight = 50.0
|
||||
drawer.segments(listOf(c0, c1, c2, c3))
|
||||
|
||||
// Show the grid
|
||||
drawer.strokeWeight = 1.0
|
||||
val n = 10
|
||||
for (i in 0..n) {
|
||||
drawer.stroke = ColorRGBa.BLACK
|
||||
drawer.lineStrip(bp.horizontal(i / n.toDouble()).adaptivePositions(0.01))
|
||||
drawer.lineStrip(bp.vertical(i / n.toDouble()).adaptivePositions(0.01))
|
||||
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.lineStrip(bpSub.horizontal(i / n.toDouble()).adaptivePositions(0.01))
|
||||
drawer.lineStrip(bpSub.vertical(i / n.toDouble()).adaptivePositions(0.01))
|
||||
}
|
||||
|
||||
// Draw the colored Bezier surface
|
||||
drawer.translate(10.0, 0.0, 0.0)
|
||||
drawer.bezierPatch(bp)
|
||||
}
|
||||
// Draw the colored Bezier surface
|
||||
drawer.translate(10.0, 0.0, 0.0)
|
||||
drawer.bezierPatch(bp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,32 +5,30 @@ import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.shapes.bezierpatches.bezierPatch
|
||||
import org.openrndr.shape.Circle
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
val bp = bezierPatch(
|
||||
Circle(width/2.0, height/2.0, 200.0).contour
|
||||
).withColors(
|
||||
listOf(
|
||||
fun main() = application {
|
||||
program {
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
val bp = bezierPatch(
|
||||
Circle(width / 2.0, height / 2.0, 200.0).contour
|
||||
).withColors(
|
||||
listOf(
|
||||
listOf(ColorRGBa.PINK, ColorRGBa.RED, ColorRGBa.BLACK, ColorRGBa.BLUE),
|
||||
listOf(ColorRGBa.RED, ColorRGBa.BLACK, ColorRGBa.BLUE, ColorRGBa.GREEN),
|
||||
listOf(ColorRGBa.PINK, ColorRGBa.RED, ColorRGBa.WHITE, ColorRGBa.GREEN),
|
||||
listOf(ColorRGBa.BLACK, ColorRGBa.WHITE, ColorRGBa.BLACK, ColorRGBa.BLUE),
|
||||
)
|
||||
listOf(ColorRGBa.RED, ColorRGBa.BLACK, ColorRGBa.BLUE, ColorRGBa.GREEN),
|
||||
listOf(ColorRGBa.PINK, ColorRGBa.RED, ColorRGBa.WHITE, ColorRGBa.GREEN),
|
||||
listOf(ColorRGBa.BLACK, ColorRGBa.WHITE, ColorRGBa.BLACK, ColorRGBa.BLUE),
|
||||
)
|
||||
)
|
||||
|
||||
drawer.bezierPatch(bp)
|
||||
drawer.bezierPatch(bp)
|
||||
|
||||
drawer.fill = null
|
||||
drawer.contour(bp.contour)
|
||||
for (i in 0 until 10) {
|
||||
drawer.contour(bp.horizontal(i/9.0))
|
||||
}
|
||||
for (i in 0 until 10) {
|
||||
drawer.contour(bp.vertical(i/9.0))
|
||||
}
|
||||
drawer.fill = null
|
||||
drawer.contour(bp.contour)
|
||||
for (i in 0 until 10) {
|
||||
drawer.contour(bp.horizontal(i / 9.0))
|
||||
}
|
||||
for (i in 0 until 10) {
|
||||
drawer.contour(bp.vertical(i / 9.0))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,43 +7,61 @@ import org.openrndr.extra.color.spaces.toOKLABa
|
||||
import org.openrndr.extra.shapes.bezierpatches.bezierPatch
|
||||
import org.openrndr.shape.Circle
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
val bp2 = bezierPatch(
|
||||
Circle(width/2.0 - 180.0, height/2.0, 170.0).contour
|
||||
).withColors(
|
||||
listOf(
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
val bp2 = bezierPatch(
|
||||
Circle(width / 2.0 - 180.0, height / 2.0, 170.0).contour
|
||||
).withColors(
|
||||
listOf(
|
||||
listOf(ColorRGBa.PINK, ColorRGBa.PINK, ColorRGBa.PINK, ColorRGBa.PINK),
|
||||
listOf(ColorRGBa.RED, ColorRGBa.RED, ColorRGBa.RED, ColorRGBa.RED),
|
||||
listOf(ColorRGBa.BLUE, ColorRGBa.BLUE, ColorRGBa.BLUE, ColorRGBa.BLUE),
|
||||
listOf(ColorRGBa.WHITE, ColorRGBa.WHITE, ColorRGBa.WHITE, ColorRGBa.WHITE),
|
||||
)
|
||||
listOf(ColorRGBa.RED, ColorRGBa.RED, ColorRGBa.RED, ColorRGBa.RED),
|
||||
listOf(ColorRGBa.BLUE, ColorRGBa.BLUE, ColorRGBa.BLUE, ColorRGBa.BLUE),
|
||||
listOf(ColorRGBa.WHITE, ColorRGBa.WHITE, ColorRGBa.WHITE, ColorRGBa.WHITE),
|
||||
)
|
||||
drawer.bezierPatch(bp2)
|
||||
val bp3 = bezierPatch(
|
||||
Circle(width/2.0 + 180.0, height/2.0, 170.0).contour
|
||||
).withColors(
|
||||
)
|
||||
drawer.bezierPatch(bp2)
|
||||
val bp3 = bezierPatch(
|
||||
Circle(width / 2.0 + 180.0, height / 2.0, 170.0).contour
|
||||
).withColors(
|
||||
listOf(
|
||||
listOf(
|
||||
listOf(ColorRGBa.PINK.toOKLABa(), ColorRGBa.PINK.toOKLABa(), ColorRGBa.PINK.toOKLABa(), ColorRGBa.PINK.toOKLABa()),
|
||||
listOf(ColorRGBa.RED.toOKLABa(), ColorRGBa.RED.toOKLABa(), ColorRGBa.RED.toOKLABa(), ColorRGBa.RED.toOKLABa()),
|
||||
listOf(ColorRGBa.BLUE.toOKLABa(), ColorRGBa.BLUE.toOKLABa(), ColorRGBa.BLUE.toOKLABa(), ColorRGBa.BLUE.toOKLABa()),
|
||||
listOf(ColorRGBa.WHITE.toOKLABa(), ColorRGBa.WHITE.toOKLABa(), ColorRGBa.WHITE.toOKLABa(), ColorRGBa.WHITE.toOKLABa()),
|
||||
)
|
||||
ColorRGBa.PINK.toOKLABa(),
|
||||
ColorRGBa.PINK.toOKLABa(),
|
||||
ColorRGBa.PINK.toOKLABa(),
|
||||
ColorRGBa.PINK.toOKLABa()
|
||||
),
|
||||
listOf(
|
||||
ColorRGBa.RED.toOKLABa(),
|
||||
ColorRGBa.RED.toOKLABa(),
|
||||
ColorRGBa.RED.toOKLABa(),
|
||||
ColorRGBa.RED.toOKLABa()
|
||||
),
|
||||
listOf(
|
||||
ColorRGBa.BLUE.toOKLABa(),
|
||||
ColorRGBa.BLUE.toOKLABa(),
|
||||
ColorRGBa.BLUE.toOKLABa(),
|
||||
ColorRGBa.BLUE.toOKLABa()
|
||||
),
|
||||
listOf(
|
||||
ColorRGBa.WHITE.toOKLABa(),
|
||||
ColorRGBa.WHITE.toOKLABa(),
|
||||
ColorRGBa.WHITE.toOKLABa(),
|
||||
ColorRGBa.WHITE.toOKLABa()
|
||||
),
|
||||
)
|
||||
drawer.bezierPatch(bp3)
|
||||
)
|
||||
drawer.bezierPatch(bp3)
|
||||
|
||||
drawer.fill = ColorRGBa.WHITE
|
||||
drawer.fontMap = loadFont("demo-data/fonts/IBMPlexMono-Regular.ttf", 16.0)
|
||||
drawer.text("RGB", width/2.0 - 180.0, height/2.0 + 200.0)
|
||||
drawer.text("OKLab", width/2.0 + 180.0, height/2.0 + 200.0)
|
||||
}
|
||||
drawer.fill = ColorRGBa.WHITE
|
||||
drawer.fontMap = loadFont("demo-data/fonts/IBMPlexMono-Regular.ttf", 16.0)
|
||||
drawer.text("RGB", width / 2.0 - 180.0, height / 2.0 + 200.0)
|
||||
drawer.text("OKLab", width / 2.0 + 180.0, height / 2.0 + 200.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,46 +13,64 @@ import org.openrndr.shape.Circle
|
||||
import org.openrndr.shape.Rectangle
|
||||
import kotlin.math.min
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
val colors = listOf(
|
||||
listOf(ColorRGBa.PINK.toOKLABa(), ColorRGBa.PINK.toOKLABa(), ColorRGBa.PINK.toOKLABa(), ColorRGBa.PINK.toOKLABa()),
|
||||
listOf(ColorRGBa.RED.toOKLABa(), ColorRGBa.RED.toOKLABa(), ColorRGBa.RED.toOKLABa(), ColorRGBa.RED.toOKLABa()),
|
||||
listOf(ColorRGBa.BLUE.toOKLABa(), ColorRGBa.BLUE.toOKLABa(), ColorRGBa.BLUE.toOKLABa(), ColorRGBa.BLUE.toOKLABa()),
|
||||
listOf(ColorRGBa.WHITE.toOKLABa(), ColorRGBa.WHITE.toOKLABa(), ColorRGBa.WHITE.toOKLABa(), ColorRGBa.WHITE.toOKLABa()),
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
val colors = listOf(
|
||||
listOf(
|
||||
ColorRGBa.PINK.toOKLABa(),
|
||||
ColorRGBa.PINK.toOKLABa(),
|
||||
ColorRGBa.PINK.toOKLABa(),
|
||||
ColorRGBa.PINK.toOKLABa()
|
||||
),
|
||||
listOf(
|
||||
ColorRGBa.RED.toOKLABa(),
|
||||
ColorRGBa.RED.toOKLABa(),
|
||||
ColorRGBa.RED.toOKLABa(),
|
||||
ColorRGBa.RED.toOKLABa()
|
||||
),
|
||||
listOf(
|
||||
ColorRGBa.BLUE.toOKLABa(),
|
||||
ColorRGBa.BLUE.toOKLABa(),
|
||||
ColorRGBa.BLUE.toOKLABa(),
|
||||
ColorRGBa.BLUE.toOKLABa()
|
||||
),
|
||||
listOf(
|
||||
ColorRGBa.WHITE.toOKLABa(),
|
||||
ColorRGBa.WHITE.toOKLABa(),
|
||||
ColorRGBa.WHITE.toOKLABa(),
|
||||
ColorRGBa.WHITE.toOKLABa()
|
||||
),
|
||||
)
|
||||
|
||||
val grid = drawer.bounds.grid(4, 4, marginX = 20.0, marginY = 20.0, gutterX = 10.0, gutterY = 10.0)
|
||||
|
||||
val cellWidth = grid[0][0].width
|
||||
val cellHeight = grid[0][0].height
|
||||
|
||||
val a = bezierPatch(Rectangle.fromCenter(Vector2(0.0, 0.0), cellWidth, cellHeight).contour)
|
||||
.withColors(colors)
|
||||
|
||||
val b = bezierPatch(
|
||||
Circle(0.0, 0.0, min(cellWidth, cellHeight) / 2.0).contour.transform(
|
||||
buildTransform {
|
||||
rotate(Vector3.UNIT_Z, 45.0)
|
||||
}
|
||||
)
|
||||
).withColors(colors)
|
||||
|
||||
val grid = drawer.bounds.grid(4,4, marginX = 20.0, marginY = 20.0, gutterX = 10.0, gutterY = 10.0)
|
||||
|
||||
val cellWidth = grid[0][0].width
|
||||
val cellHeight = grid[0][0].height
|
||||
|
||||
val a = bezierPatch(Rectangle.fromCenter(Vector2(0.0, 0.0), cellWidth, cellHeight).contour)
|
||||
.withColors(colors)
|
||||
|
||||
val b = bezierPatch(
|
||||
Circle(0.0, 0.0, min(cellWidth, cellHeight) / 2.0).contour.transform(
|
||||
buildTransform {
|
||||
rotate(Vector3.UNIT_Z, 45.0)
|
||||
}
|
||||
)
|
||||
).withColors(colors)
|
||||
|
||||
for (y in grid.indices) {
|
||||
for (x in grid[y].indices) {
|
||||
val f = (y * grid[y].size + x).toDouble() / (grid.size * grid[y].size - 1.0)
|
||||
val blend = a * (1.0 - f) + b * f
|
||||
drawer.isolated {
|
||||
drawer.translate(grid[y][x].center)
|
||||
drawer.bezierPatch(blend)
|
||||
}
|
||||
for (y in grid.indices) {
|
||||
for (x in grid[y].indices) {
|
||||
val f = (y * grid[y].size + x).toDouble() / (grid.size * grid[y].size - 1.0)
|
||||
val blend = a * (1.0 - f) + b * f
|
||||
drawer.isolated {
|
||||
drawer.translate(grid[y][x].center)
|
||||
drawer.bezierPatch(blend)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,23 +15,21 @@ import org.openrndr.shape.ShapeContour
|
||||
* but one can manually create any other 4-segment closed contour
|
||||
* to use in bezier patches.
|
||||
*/
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
val c0 = Circle(width / 3.0, height / 2.0, 150.0).contour
|
||||
val bp0 = bezierPatch(c0)
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
val c0 = Circle(width / 3.0, height / 2.0, 150.0).contour
|
||||
val bp0 = bezierPatch(c0)
|
||||
|
||||
val c1 = Circle(2.0*width / 3.0, height / 2.0, 150.0).contour
|
||||
val bp1 = bezierPatch(c1)
|
||||
val c1 = Circle(2.0 * width / 3.0, height / 2.0, 150.0).contour
|
||||
val bp1 = bezierPatch(c1)
|
||||
|
||||
|
||||
extend {
|
||||
drawer.bezierPatches(listOf(bp0, bp1))
|
||||
}
|
||||
extend {
|
||||
drawer.bezierPatches(listOf(bp0, bp1))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,26 +10,23 @@ import org.openrndr.shape.Circle
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.cos
|
||||
|
||||
|
||||
/**
|
||||
* Demonstration of uniform contour blending
|
||||
*/
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val a = Circle(Vector2.ZERO, 90.0).contour
|
||||
val b = regularStar(5, 30.0, 90.0, center = Vector2.ZERO, phase = 180.0)
|
||||
val blend = a.blend(b)
|
||||
extend {
|
||||
drawer.bounds.grid(3, 3).flatten().forEachIndexed { index, it ->
|
||||
drawer.isolated {
|
||||
drawer.translate(it.center)
|
||||
drawer.contour(blend.mix(cos(index * PI * 2.0 / 9.0 + seconds) * 0.5 + 0.5))
|
||||
}
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val a = Circle(Vector2.ZERO, 90.0).contour
|
||||
val b = regularStar(5, 30.0, 90.0, center = Vector2.ZERO, phase = 180.0)
|
||||
val blend = a.blend(b)
|
||||
extend {
|
||||
drawer.bounds.grid(3, 3).flatten().forEachIndexed { index, it ->
|
||||
drawer.isolated {
|
||||
drawer.translate(it.center)
|
||||
drawer.contour(blend.mix(cos(index * PI * 2.0 / 9.0 + seconds) * 0.5 + 0.5))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,24 +14,22 @@ import kotlin.math.cos
|
||||
/**
|
||||
* Demonstration of non-uniform contour blending
|
||||
*/
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val a = Circle(Vector2.ZERO, 90.0).contour
|
||||
val b = regularStar(5, 30.0, 90.0, center = Vector2.ZERO, phase = 180.0)
|
||||
val blend = a.blend(b)
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.WHITE)
|
||||
drawer.fill = ColorRGBa.BLACK
|
||||
drawer.bounds.grid(3, 3).flatten().forEachIndexed { index, it ->
|
||||
drawer.isolated {
|
||||
drawer.translate(it.center)
|
||||
drawer.contour(blend.mix { t -> cos(t * PI * 2.0 + index * PI * 2.0 / 9.0 + seconds) * 0.5 + 0.5 })
|
||||
}
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val a = Circle(Vector2.ZERO, 90.0).contour
|
||||
val b = regularStar(5, 30.0, 90.0, center = Vector2.ZERO, phase = 180.0)
|
||||
val blend = a.blend(b)
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.WHITE)
|
||||
drawer.fill = ColorRGBa.BLACK
|
||||
drawer.bounds.grid(3, 3).flatten().forEachIndexed { index, it ->
|
||||
drawer.isolated {
|
||||
drawer.translate(it.center)
|
||||
drawer.contour(blend.mix { t -> cos(t * PI * 2.0 + index * PI * 2.0 / 9.0 + seconds) * 0.5 + 0.5 })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,52 +15,49 @@ import org.openrndr.math.Vector3
|
||||
import org.openrndr.shape.path3D
|
||||
import kotlin.random.Random
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
multisample = WindowMultisample.SampleCount(4)
|
||||
}
|
||||
program {
|
||||
val random = Random(0)
|
||||
val cylinder = cylinderMesh(radius = 0.5, length = 0.1)
|
||||
val p = path3D {
|
||||
moveTo(0.0, 0.0, 0.0)
|
||||
curveTo(
|
||||
Vector3.uniformRing(0.1, 1.0, random = random)*10.0,
|
||||
Vector3.uniformRing(0.1, 1.0, random = random)*10.0,
|
||||
Vector3.uniformRing(0.1, 1.0, random = random)*10.0
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
multisample = WindowMultisample.SampleCount(4)
|
||||
}
|
||||
program {
|
||||
val random = Random(0)
|
||||
val cylinder = cylinderMesh(radius = 0.5, length = 0.1)
|
||||
val p = path3D {
|
||||
moveTo(0.0, 0.0, 0.0)
|
||||
curveTo(
|
||||
Vector3.uniformRing(0.1, 1.0, random = random) * 10.0,
|
||||
Vector3.uniformRing(0.1, 1.0, random = random) * 10.0,
|
||||
Vector3.uniformRing(0.1, 1.0, random = random) * 10.0
|
||||
)
|
||||
for (i in 0 until 10) {
|
||||
continueTo(
|
||||
Vector3.uniformRing(0.1, 1.0, random = random) * 10.0,
|
||||
Vector3.uniformRing(0.1, 1.0, random = random) * 10.0
|
||||
)
|
||||
for (i in 0 until 10) {
|
||||
continueTo(
|
||||
Vector3.uniformRing(0.1, 1.0, random = random)*10.0,
|
||||
Vector3.uniformRing(0.1, 1.0, random = random)*10.0
|
||||
)
|
||||
}
|
||||
}
|
||||
val pr = p.rectified(0.01, 100.0)
|
||||
}
|
||||
val pr = p.rectified(0.01, 100.0)
|
||||
|
||||
|
||||
val frames = pr.frames((0 until 100).map { it / 100.0}, Vector3.UNIT_Y, analyticalDirections = false)
|
||||
extend(Orbital())
|
||||
extend {
|
||||
drawer.shadeStyle = shadeStyle {
|
||||
fragmentTransform = """
|
||||
val frames = pr.frames((0 until 100).map { it / 100.0 }, Vector3.UNIT_Y, analyticalDirections = false)
|
||||
extend(Orbital())
|
||||
extend {
|
||||
drawer.shadeStyle = shadeStyle {
|
||||
fragmentTransform = """
|
||||
x_fill.rgb = vec3(abs(v_viewNormal.z)*0.9+ 0.1);
|
||||
""".trimIndent()
|
||||
}
|
||||
|
||||
drawer.stroke = ColorRGBa.PINK
|
||||
drawer.path(p)
|
||||
|
||||
for (frame in frames) {
|
||||
drawer.isolated {
|
||||
drawer.model = frame
|
||||
drawer.vertexBuffer(cylinder, DrawPrimitive.TRIANGLES)
|
||||
}
|
||||
|
||||
drawer.stroke = ColorRGBa.PINK
|
||||
drawer.path(p)
|
||||
|
||||
for (frame in frames) {
|
||||
drawer.isolated {
|
||||
drawer.model = frame
|
||||
drawer.vertexBuffer(cylinder, DrawPrimitive.TRIANGLES)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,20 +6,18 @@ import org.openrndr.extra.noise.uniform
|
||||
import org.openrndr.extra.shapes.ordering.hilbertOrder
|
||||
import kotlin.random.Random
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val points = drawer.bounds.offsetEdges(-20.0).uniform(40, Random(0))
|
||||
val sortedPoints = points.hilbertOrder(bits = 16, scale = 1.0)
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.lineStrip(sortedPoints)
|
||||
}
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val points = drawer.bounds.offsetEdges(-20.0).uniform(40, Random(0))
|
||||
val sortedPoints = points.hilbertOrder(bits = 16, scale = 1.0)
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.lineStrip(sortedPoints)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,26 +4,23 @@ import org.openrndr.application
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.noise.uniform
|
||||
import org.openrndr.extra.shapes.ordering.hilbertOrder
|
||||
import org.openrndr.extra.shapes.ordering.mortonOrder
|
||||
import kotlin.random.Random
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val points = drawer.bounds.offsetEdges(-20.0).uniform(400, Random(0))
|
||||
val sortedPoints0 = points.hilbertOrder(bits = 16, scale = 1.0)
|
||||
val sortedPoints1 = points.map { it.xy0 }.hilbertOrder(bits = 10, scale = 1.0).map { it.xy }
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.lineStrip(sortedPoints0)
|
||||
drawer.stroke = ColorRGBa.BLUE
|
||||
drawer.lineStrip(sortedPoints1)
|
||||
}
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val points = drawer.bounds.offsetEdges(-20.0).uniform(400, Random(0))
|
||||
val sortedPoints0 = points.hilbertOrder(bits = 16, scale = 1.0)
|
||||
val sortedPoints1 = points.map { it.xy0 }.hilbertOrder(bits = 10, scale = 1.0).map { it.xy }
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.lineStrip(sortedPoints0)
|
||||
drawer.stroke = ColorRGBa.BLUE
|
||||
drawer.lineStrip(sortedPoints1)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,38 +4,31 @@ import org.openrndr.application
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.draw.LineJoin
|
||||
import org.openrndr.extra.camera.Orbital
|
||||
import org.openrndr.extra.noise.uniformRing
|
||||
import org.openrndr.extra.shapes.path3d.projectToContour
|
||||
import org.openrndr.math.Spherical
|
||||
import org.openrndr.math.Vector3
|
||||
import org.openrndr.shape.path3D
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
fun main() = application {
|
||||
program {
|
||||
val path = path3D {
|
||||
var p = Vector3(6.0, 0.0, 0.0)
|
||||
moveTo(p)
|
||||
for (i in 0 until 100) {
|
||||
p = Spherical((i % 6) * 45.0, (i % 4 + 1) * 30.0 + i * 0.1, 6.0).cartesian
|
||||
arcTo(5.0, cursor.atan2(p), false, false, p)
|
||||
}
|
||||
}
|
||||
program {
|
||||
val path = path3D {
|
||||
var p = Vector3(1.0, 0.0, 0.0)
|
||||
moveTo(p * 6.0)
|
||||
for (i in 0 until 400) {
|
||||
p += Vector3.uniformRing(0.2, 0.5)
|
||||
p = p.normalized
|
||||
arcTo(5.0, cursor.atan2(p * 6.0), false, false, p * 6.0)
|
||||
}
|
||||
}
|
||||
extend(Orbital())
|
||||
extend {
|
||||
drawer.stroke = ColorRGBa.PINK
|
||||
drawer.path(path)
|
||||
val c = path.projectToContour(drawer.projection, drawer.view, width, height)
|
||||
drawer.defaults()
|
||||
drawer.stroke = ColorRGBa.WHITE
|
||||
drawer.lineJoin = LineJoin.ROUND
|
||||
drawer.strokeWeight = 2.0
|
||||
drawer.contour(c)
|
||||
}
|
||||
extend(Orbital())
|
||||
extend {
|
||||
drawer.stroke = ColorRGBa.PINK
|
||||
drawer.path(path)
|
||||
val c = path.projectToContour(drawer.projection, drawer.view, width, height)
|
||||
drawer.defaults()
|
||||
drawer.stroke = ColorRGBa.WHITE
|
||||
drawer.lineJoin = LineJoin.ROUND
|
||||
drawer.strokeWeight = 2.0
|
||||
drawer.contour(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,21 +4,19 @@ import org.openrndr.application
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.shapes.primitives.Arc
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
val a = Arc(drawer.bounds.center, 100.0, 0.0 + seconds * 36.0, -180.0 + seconds * 36.0)
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
drawer.contour(a.contour)
|
||||
drawer.circle(a.position(0.0), 5.0)
|
||||
drawer.circle(a.position(0.5), 5.0)
|
||||
drawer.circle(a.position(1.0), 5.0)
|
||||
}
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
val a = Arc(drawer.bounds.center, 100.0, 0.0 + seconds * 36.0, -180.0 + seconds * 36.0)
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
drawer.contour(a.contour)
|
||||
drawer.circle(a.position(0.0), 5.0)
|
||||
drawer.circle(a.position(0.5), 5.0)
|
||||
drawer.circle(a.position(1.0), 5.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,29 +6,27 @@ import org.openrndr.extra.shapes.primitives.Net
|
||||
import org.openrndr.shape.Circle
|
||||
import kotlin.math.sin
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
program {
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
drawer.stroke = ColorRGBa.WHITE
|
||||
drawer.fill = ColorRGBa.PINK
|
||||
val a = drawer.bounds.position(0.7, 0.5)
|
||||
val b = drawer.bounds.position(0.3, 0.5)
|
||||
val c = Circle(
|
||||
drawer.bounds.position(
|
||||
sin(seconds) * 0.35 + 0.5,
|
||||
sin(seconds * 2) * 0.25 + 0.5
|
||||
), 50.0
|
||||
)
|
||||
val net = Net(a, b, c)
|
||||
drawer.circle(a, 10.0)
|
||||
drawer.circle(b, 10.0)
|
||||
drawer.circle(c)
|
||||
fun main() = application {
|
||||
program {
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
drawer.stroke = ColorRGBa.WHITE
|
||||
drawer.fill = ColorRGBa.PINK
|
||||
val a = drawer.bounds.position(0.7, 0.5)
|
||||
val b = drawer.bounds.position(0.3, 0.5)
|
||||
val c = Circle(
|
||||
drawer.bounds.position(
|
||||
sin(seconds) * 0.35 + 0.5,
|
||||
sin(seconds * 2) * 0.25 + 0.5
|
||||
), 50.0
|
||||
)
|
||||
val net = Net(a, b, c)
|
||||
drawer.circle(a, 10.0)
|
||||
drawer.circle(b, 10.0)
|
||||
drawer.circle(c)
|
||||
|
||||
drawer.strokeWeight = 2.0
|
||||
drawer.contour(net.contour)
|
||||
}
|
||||
drawer.strokeWeight = 2.0
|
||||
drawer.contour(net.contour)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,23 +6,21 @@ import org.openrndr.extra.shapes.primitives.Pulley
|
||||
import org.openrndr.math.Vector2
|
||||
import org.openrndr.shape.Circle
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
drawer.stroke = ColorRGBa.WHITE
|
||||
drawer.fill = ColorRGBa.PINK
|
||||
val pulley = Pulley(
|
||||
Circle(drawer.bounds.center - Vector2(100.0, 100.0), 150.0),
|
||||
Circle(drawer.bounds.center + Vector2(150.0, 150.0), 75.0)
|
||||
)
|
||||
drawer.contour(pulley.contour)
|
||||
}
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
drawer.stroke = ColorRGBa.WHITE
|
||||
drawer.fill = ColorRGBa.PINK
|
||||
val pulley = Pulley(
|
||||
Circle(drawer.bounds.center - Vector2(100.0, 100.0), 150.0),
|
||||
Circle(drawer.bounds.center + Vector2(150.0, 150.0), 75.0)
|
||||
)
|
||||
drawer.contour(pulley.contour)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,24 +4,22 @@ import org.openrndr.application
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.shapes.primitives.grid
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
drawer.fill = ColorRGBa.WHITE.opacify(0.25)
|
||||
drawer.stroke = ColorRGBa.PINK
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
drawer.fill = ColorRGBa.WHITE.opacify(0.25)
|
||||
drawer.stroke = ColorRGBa.PINK
|
||||
|
||||
// Notice the negative gutter in this grid. It creates an
|
||||
// overlap between the resulting rectangles.
|
||||
val grid = drawer.bounds.grid(8, 4, 20.0, 20.0, -20.0, -20.0)
|
||||
for (cell in grid.flatten()) {
|
||||
drawer.rectangle(cell)
|
||||
drawer.lineSegment(cell.position(0.0, 0.0), cell.position(1.0, 1.0))
|
||||
}
|
||||
// Notice the negative gutter in this grid. It creates an
|
||||
// overlap between the resulting rectangles.
|
||||
val grid = drawer.bounds.grid(8, 4, 20.0, 20.0, -20.0, -20.0)
|
||||
for (cell in grid.flatten()) {
|
||||
drawer.rectangle(cell)
|
||||
drawer.lineSegment(cell.position(0.0, 0.0), cell.position(1.0, 1.0))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,35 +5,35 @@ import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.noise.Random
|
||||
import org.openrndr.extra.shapes.primitives.grid
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
// Try changing the resolution. The design will use the available space.
|
||||
configure {
|
||||
width = 800
|
||||
height = 400
|
||||
}
|
||||
program {
|
||||
// By specifying the cell size we make sure the design will
|
||||
// contain squares, independently of the window size and its
|
||||
// aspect ratio.
|
||||
val grid = drawer.bounds.grid(50.0, 50.0,
|
||||
20.0, 20.0, 20.0, 20.0).flatten()
|
||||
fun main() = application {
|
||||
// Try changing the resolution. The design will use the available space.
|
||||
configure {
|
||||
width = 800
|
||||
height = 400
|
||||
}
|
||||
program {
|
||||
// By specifying the cell size we make sure the design will
|
||||
// contain squares, independently of the window size and its
|
||||
// aspect ratio.
|
||||
val grid = drawer.bounds.grid(
|
||||
50.0, 50.0,
|
||||
20.0, 20.0, 20.0, 20.0
|
||||
).flatten()
|
||||
|
||||
val grid2 = grid.map { rect ->
|
||||
// Each of these inner grids will occupy the available space
|
||||
// in the parent grid cells. Notice how we don't specify cell
|
||||
// sizes here but counts instead (between 1 and 3 columns and
|
||||
// rows)
|
||||
val count = Random.int(1, 4)
|
||||
rect.grid(count, count, 5.0, 5.0, 5.0, 5.0).flatten()
|
||||
}.flatten().filter { Random.bool(0.5)}
|
||||
val grid2 = grid.map { rect ->
|
||||
// Each of these inner grids will occupy the available space
|
||||
// in the parent grid cells. Notice how we don't specify cell
|
||||
// sizes here but counts instead (between 1 and 3 columns and
|
||||
// rows)
|
||||
val count = Random.int(1, 4)
|
||||
rect.grid(count, count, 5.0, 5.0, 5.0, 5.0).flatten()
|
||||
}.flatten().filter { Random.bool(0.5) }
|
||||
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
drawer.rectangles(grid)
|
||||
drawer.fill = ColorRGBa.BLACK
|
||||
drawer.rectangles(grid2)
|
||||
}
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
drawer.rectangles(grid)
|
||||
drawer.fill = ColorRGBa.BLACK
|
||||
drawer.rectangles(grid2)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,33 +8,31 @@ import org.openrndr.extra.shapes.primitives.intersection
|
||||
* Demonstrate rectangle-rectangle intersection
|
||||
* @see <img src="https://raw.githubusercontent.com/openrndr/orx/media/orx-shapes/images/primitives-DemoRectangleIntersection01Kt.png">
|
||||
*/
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val h = drawer.bounds.offsetEdges(-100.0, -10.0)
|
||||
val v = drawer.bounds.offsetEdges(-10.0, -100.0)
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val h = drawer.bounds.offsetEdges(-100.0, -10.0)
|
||||
val v = drawer.bounds.offsetEdges(-10.0, -100.0)
|
||||
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.WHITE)
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.WHITE)
|
||||
|
||||
/**
|
||||
* Find intersection
|
||||
*/
|
||||
val i = h.intersection(v)
|
||||
drawer.fill = ColorRGBa.RED
|
||||
drawer.rectangle(h)
|
||||
/**
|
||||
* Find intersection
|
||||
*/
|
||||
val i = h.intersection(v)
|
||||
drawer.fill = ColorRGBa.RED
|
||||
drawer.rectangle(h)
|
||||
|
||||
drawer.fill = ColorRGBa.BLUE
|
||||
drawer.rectangle(v)
|
||||
drawer.fill = ColorRGBa.BLUE
|
||||
drawer.rectangle(v)
|
||||
|
||||
drawer.fill = ColorRGBa.BLACK
|
||||
drawer.stroke = ColorRGBa.WHITE
|
||||
drawer.rectangle(i)
|
||||
}
|
||||
drawer.fill = ColorRGBa.BLACK
|
||||
drawer.stroke = ColorRGBa.WHITE
|
||||
drawer.rectangle(i)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,24 +8,22 @@ import org.openrndr.math.Vector2
|
||||
import org.openrndr.shape.Circle
|
||||
import kotlin.random.Random
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val points = drawer.bounds.scatter(40.0, distanceToEdge = 150.0, random = Random(0))
|
||||
val tears = points.map {
|
||||
Tear(it - Vector2(0.0, 20.0), Circle(it + Vector2(0.0, 20.0), 20.0))
|
||||
}
|
||||
program {
|
||||
val points = drawer.bounds.scatter(40.0, distanceToEdge = 150.0, random = Random(0))
|
||||
val tears = points.map {
|
||||
Tear(it - Vector2(0.0, 20.0), Circle(it + Vector2(0.0, 20.0), 20.0))
|
||||
}
|
||||
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
drawer.fill = ColorRGBa.PINK
|
||||
drawer.stroke = ColorRGBa.WHITE
|
||||
drawer.contours(tears.map { it.contour })
|
||||
}
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
drawer.fill = ColorRGBa.PINK
|
||||
drawer.stroke = ColorRGBa.WHITE
|
||||
drawer.contours(tears.map { it.contour })
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,26 +7,24 @@ import org.openrndr.extra.shapes.hobbycurve.hobbyCurve
|
||||
import org.openrndr.extra.shapes.rectify.rectified
|
||||
import kotlin.random.Random
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val points = drawer.bounds.scatter(50.0, distanceToEdge = 100.0, random = Random(0))
|
||||
val curve = hobbyCurve(points)
|
||||
val rectified = curve.rectified()
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
drawer.stroke = ColorRGBa.PINK
|
||||
drawer.contour(curve)
|
||||
drawer.fill = ColorRGBa.RED
|
||||
drawer.circle(curve.position(seconds*0.05), 10.0)
|
||||
drawer.fill = ColorRGBa.GREEN
|
||||
drawer.circle(rectified.position(seconds*0.05), 10.0)
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val points = drawer.bounds.scatter(50.0, distanceToEdge = 100.0, random = Random(0))
|
||||
val curve = hobbyCurve(points)
|
||||
val rectified = curve.rectified()
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
drawer.stroke = ColorRGBa.PINK
|
||||
drawer.contour(curve)
|
||||
drawer.fill = ColorRGBa.RED
|
||||
drawer.circle(curve.position(seconds * 0.05), 10.0)
|
||||
drawer.fill = ColorRGBa.GREEN
|
||||
drawer.circle(rectified.position(seconds * 0.05), 10.0)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,29 +7,27 @@ import org.openrndr.extra.shapes.hobbycurve.hobbyCurve
|
||||
import org.openrndr.extra.shapes.rectify.rectified
|
||||
import kotlin.random.Random
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val points = drawer.bounds.scatter(80.0, distanceToEdge = 100.0, random = Random(0))
|
||||
val curve = hobbyCurve(points, closed = true)
|
||||
val rectified = curve.rectified()
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
drawer.fill = null
|
||||
drawer.stroke = ColorRGBa.GRAY
|
||||
drawer.contour(curve)
|
||||
drawer.strokeWeight = 4.0
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val points = drawer.bounds.scatter(80.0, distanceToEdge = 100.0, random = Random(0))
|
||||
val curve = hobbyCurve(points, closed = true)
|
||||
val rectified = curve.rectified()
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
drawer.fill = null
|
||||
drawer.stroke = ColorRGBa.GRAY
|
||||
drawer.contour(curve)
|
||||
drawer.strokeWeight = 4.0
|
||||
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.contour(curve.sub(seconds*0.1, seconds*0.1+0.01))
|
||||
drawer.stroke = ColorRGBa.RED
|
||||
drawer.contour(curve.sub(seconds * 0.1, seconds * 0.1 + 0.01))
|
||||
|
||||
drawer.stroke = ColorRGBa.GREEN
|
||||
drawer.contour(rectified.sub(seconds*0.1, seconds*0.1+0.01))
|
||||
}
|
||||
drawer.stroke = ColorRGBa.GREEN
|
||||
drawer.contour(rectified.sub(seconds * 0.1, seconds * 0.1 + 0.01))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,28 +7,26 @@ import org.openrndr.extra.shapes.hobbycurve.hobbyCurve
|
||||
import org.openrndr.extra.shapes.rectify.rectified
|
||||
import kotlin.random.Random
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val points = drawer.bounds.scatter(80.0, distanceToEdge = 100.0, random = Random(0))
|
||||
val curve = hobbyCurve(points, closed = true)
|
||||
val rectified = curve.rectified()
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
drawer.fill = null
|
||||
drawer.stroke = ColorRGBa.GRAY
|
||||
drawer.contour(curve)
|
||||
|
||||
val points = (0 until 100).map {
|
||||
rectified.position(it/100.0)
|
||||
}
|
||||
drawer.circles(points, 5.0)
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val points = drawer.bounds.scatter(80.0, distanceToEdge = 100.0, random = Random(0))
|
||||
val curve = hobbyCurve(points, closed = true)
|
||||
val rectified = curve.rectified()
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
drawer.fill = null
|
||||
drawer.stroke = ColorRGBa.GRAY
|
||||
drawer.contour(curve)
|
||||
|
||||
val points = (0 until 100).map {
|
||||
rectified.position(it / 100.0)
|
||||
}
|
||||
drawer.circles(points, 5.0)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,38 +12,35 @@ import org.openrndr.extra.shapes.rectify.rectified
|
||||
import org.openrndr.math.Vector3
|
||||
import org.openrndr.shape.path3D
|
||||
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
multisample = WindowMultisample.SampleCount(4)
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
multisample = WindowMultisample.SampleCount(4)
|
||||
}
|
||||
program {
|
||||
val p = path3D {
|
||||
moveTo(0.0, 0.0, 0.0)
|
||||
for (i in 0 until 10) {
|
||||
curveTo(
|
||||
Vector3.uniformRing(0.1, 1.0) * 10.0,
|
||||
Vector3.uniformRing(0.1, 1.0) * 10.0,
|
||||
Vector3.uniformRing(0.1, 1.0) * 10.0
|
||||
)
|
||||
}
|
||||
}
|
||||
program {
|
||||
val p = path3D {
|
||||
moveTo(0.0, 0.0, 0.0)
|
||||
for (i in 0 until 10) {
|
||||
curveTo(
|
||||
Vector3.uniformRing(0.1, 1.0)*10.0,
|
||||
Vector3.uniformRing(0.1, 1.0)*10.0,
|
||||
Vector3.uniformRing(0.1, 1.0)*10.0
|
||||
)
|
||||
val pr = p.rectified(0.01, 100.0)
|
||||
val sphere = sphereMesh(radius = 0.1)
|
||||
extend(Orbital())
|
||||
extend {
|
||||
drawer.stroke = ColorRGBa.PINK
|
||||
for (i in 0 until 500) {
|
||||
drawer.isolated {
|
||||
drawer.translate(pr.position(i / 499.0))
|
||||
drawer.vertexBuffer(sphere, DrawPrimitive.TRIANGLES)
|
||||
}
|
||||
}
|
||||
val pr = p.rectified(0.01, 100.0)
|
||||
val sphere = sphereMesh(radius = 0.1)
|
||||
extend(Orbital())
|
||||
extend {
|
||||
drawer.stroke = ColorRGBa.PINK
|
||||
for (i in 0 until 500) {
|
||||
drawer.isolated {
|
||||
drawer.translate(pr.position(i/499.0))
|
||||
drawer.vertexBuffer(sphere, DrawPrimitive.TRIANGLES)
|
||||
}
|
||||
}
|
||||
drawer.path(p)
|
||||
}
|
||||
drawer.path(p)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,26 +6,23 @@ import org.openrndr.draw.font.loadFace
|
||||
import org.openrndr.extra.shapes.bounds.bounds
|
||||
import org.openrndr.extra.shapes.text.shapesFromText
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val face =
|
||||
loadFace("https://github.com/IBM/plex/raw/master/packages/plex-mono/fonts/complete/otf/IBMPlexMono-Bold.otf")
|
||||
val shapes = shapesFromText(face, "SUCH\nVECTOR\nSUCH\nTEXT", 150.0)
|
||||
|
||||
val face =
|
||||
loadFace("https://github.com/IBM/plex/raw/master/packages/plex-mono/fonts/complete/otf/IBMPlexMono-Bold.otf")
|
||||
val shapes = shapesFromText(face, "SUCH\nVECTOR\nSUCH\nTEXT", 150.0)
|
||||
|
||||
val bounds = shapes.bounds
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
drawer.translate(-bounds.corner)
|
||||
drawer.translate((width - bounds.width) / 2.0, (height - bounds.height) / 2.0)
|
||||
drawer.shapes(shapes)
|
||||
}
|
||||
val bounds = shapes.bounds
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
drawer.translate(-bounds.corner)
|
||||
drawer.translate((width - bounds.width) / 2.0, (height - bounds.height) / 2.0)
|
||||
drawer.shapes(shapes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user