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