Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions orx-shapes/src/jvmDemo/kotlin/primitives/DemoCircleInversion01.kt
Original file line number Diff line number Diff line change
@@ -1,19 +1,36 @@
package primitives

import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.extra.shapes.primitives.invert
import org.openrndr.math.Vector2
import org.openrndr.shape.Circle

/**
* Demonstrates how to use a Circle's `invert()` method, to map a point
* (in this case, the mouse position) to another point along the same
* ray from the center, but at a distance that is inversely proportional
* to the original distance.
*
* If the distance from the center of the circle to the point being inverted
* is zero, an `IllegalArgumentException` is thrown. Since the mouse position
* is rounded to whole numbers, we ensure that exception will not happen by slightly
* offsetting the center of the circle.
*/
fun main() = application {
configure {
width = 720
height = 720
}
program {
val c = Circle(drawer.bounds.center + Vector2(1E-2, 1E-2), 100.0)
extend {
val c = Circle(drawer.bounds.center + Vector2(1E-2, 1E-2), 100.0)
drawer.circle(c.invert(mouse.position),10.0)
val invertedPos = c.invert(mouse.position)

drawer.fill = null
drawer.stroke = ColorRGBa.WHITE
drawer.circle(c)
drawer.circle(invertedPos,10.0)
}
}
}
27 changes: 27 additions & 0 deletions orx-shapes/src/jvmDemo/kotlin/primitives/DemoCircleInversion02.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,25 @@ import org.openrndr.extra.shapes.primitives.invertConformal
import org.openrndr.math.Polar
import org.openrndr.shape.Circle

/**
* Demonstrates the use of the `Circle`'s `.invertConformal()` method:
* a special type of circle inversion that preserves tangency
* between circles. If two circles are tangent, their images
* under conformal inversion will also be tangent.
*
* The program calculates a moving circle (`mc`) traveling around the
* center of the screen.
*
* It then calculates a grid of 10x10 circles covering the window
* area. Those circles are inverted using `.invertConformal()`
* against `mc`.
*
* This calculation is performed twice: the first pass draws those
* grid circles that contain the moving circle's center in black.
*
* The second pass draws grid circles that do not contain the moving
* circle's center in white.
*/
fun main() = application {
configure {
width = 720
Expand Down Expand Up @@ -47,8 +66,16 @@ fun main() = application {
is Circle -> drawer.circle(ci)
}
}
// show the static grid of circles
//drawer.circle(c)
}
}

// show the moving circle
//drawer.stroke = ColorRGBa.PINK
//drawer.strokeWeight = 2.0
//drawer.fill = null
//drawer.circle(mc)
}
}
}
11 changes: 11 additions & 0 deletions orx-shapes/src/jvmDemo/kotlin/primitives/DemoCircleInversion03.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@ import org.openrndr.shape.LineSegment
import kotlin.math.cos
import kotlin.math.sin

/**
* Demonstrates one of the implementations of `Circle.invert()`
* which takes a `LineSegment` and returns a `Circle`, an `Arc`
* or a `LineSegment`.
*
* The program generates 10 evenly spaced vertical line segments
* and 10 horizontal line segments. An animated `sub` segment
* is calculated using the sine of the current time in seconds.
* These `sub` segments are then inverted using
* an animated circle moving around the center of the screen.
*/
fun main() = application {
configure {
width = 720
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,24 @@ import org.openrndr.extra.shapes.primitives.distributeHorizontally
import kotlin.math.cos
import kotlin.random.Random

/** This function creates an interactive graphical application that displays a dynamic visual composition
* of rectangles, which are generated and manipulated based on time and random parameters. The application
* follows these steps:
/**
* This program demonstrates three Rectangle-related methods:
* `uniformSub()`, `distributeHorizontally()` and `alignToVertically()`.
*
* 1. Initializes a random generator seeded with the elapsed seconds since the start of the program.
* 2. Creates a sequence of rectangles using the `uniformSub` function to generate random sub-rectangles
* within the bounding rectangle of the canvas.
* 3. Distributes the generated rectangles horizontally within the canvas using the `distributeHorizontally` method.
* 4. Aligns the rectangles vertically according to their position in relation to the bounding rectangle
* and a dynamic anchor point derived from the cosine of elapsed time.
* 5. Renders the rectangles on the canvas in the output window.
* `uniformSub` is used to create a sub Rectangle of the window bounds. By default, its arguments
* allow any width and height between 0.0 and 1.0 (full width). In this program we override
* the minimum and maximum random widths. `uniformSub` takes a `random` parameter, which
* we change only once per second by rounding `seconds` to an integer. This randomizes
* the widths every second.
*
* At this point in the program we have a List with 7 random sub rectangles, potentially
* overlapping each other. By calling `.distributeHorizontally()` we displace the
* rectangles so the horizontal space between them is equal.
*
* Finally, we call `alignToVertically()` with a sine wave of time as an argument, to interpolate
* their vertical position between being top-aligned and bottom-aligned.
*
* Try commenting out one or both of the last two function calls to observe the resulting changes.
*/
fun main() {
application {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package primitives

import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.extra.noise.shapes.uniformSub
import org.openrndr.extra.shapes.primitives.alignToHorizontally
import org.openrndr.extra.shapes.primitives.alignToVertically
Expand All @@ -9,21 +10,36 @@ import org.openrndr.extra.shapes.primitives.fitVertically
import kotlin.math.cos
import kotlin.random.Random

/**
* This program animates two sets of 7 rectangles.
*
* The first set contains vertical rectangles with random widths.
* The call to `fitHorizontally()` adjusts the widths of the rectangles
* so they cover the available horizontal space, leaving a gutter space
* between the shapes. In this demo the gutter space is adjusted based
* on the vertical mouse position.
* The vertical position of the rectangles is animated between
* top-aligned and bottom-aligned using `seconds` and the sine function.
*
* The second set contains horizontal rectangles, their heights are
* adjusted using `fitVertically()` to cover the available vertical space,
* and are animated horizontally between left-aligned and right-aligned.
*/
fun main() = application {
configure {
width = 720
height = 720
}
program {
extend {
val rs = (0 until 7).map { drawer.bounds.uniformSub(minWidth = 0.01, maxWidth = 0.1, random = Random(it)) }
val rs = (0 until 7).map { drawer.bounds.uniformSub(minWidth = 0.01, maxWidth = 0.1, random = Random(it + 123)) }
.fitHorizontally(drawer.bounds, gutter = 30.0 * mouse.position.y / height)
.alignToVertically(drawer.bounds, cos(seconds) * 0.5 + 0.5)

drawer.rectangles(rs)


val rsh = (0 until 7).map { drawer.bounds.uniformSub(minHeight = 0.01, maxHeight = 0.1, random = Random(it)) }
val rsh = (0 until 7).map { drawer.bounds.uniformSub(minHeight = 0.01, maxHeight = 0.1, random = Random(it + 101)) }
.fitVertically(drawer.bounds, gutter = 30.0 * mouse.position.y / height)
.alignToHorizontally(drawer.bounds, cos(seconds) * 0.5 + 0.5)

Expand Down
10 changes: 10 additions & 0 deletions orx-shapes/src/jvmDemo/kotlin/primitives/DemoRectangleGrid01.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.extra.shapes.primitives.grid

/**
* Demonstrates the use of `Rectangle.grid()` to produce a list of lists of Rectangles.
* When calling `grid()` this demo specifies the number of columns and rows, the horizontal
* and vertical margin around the grid, and the horizontal and vertical gutter space
* between the grid cells.
*
* The rectangles are rendered with reduced opacity to reveal the overlaps produced
* by the negative gutter spaces. A diagonal line is rendered between the top-left
* and bottom-right corners of each cell.
*/
fun main() = application {
configure {
width = 800
Expand Down
15 changes: 13 additions & 2 deletions orx-shapes/src/jvmDemo/kotlin/primitives/DemoRectangleGrid02.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,19 @@ package primitives
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.extra.noise.Random
import org.openrndr.extra.noise.primitives.random
import org.openrndr.extra.noise.uniform
import org.openrndr.extra.shapes.primitives.grid

/**
* Demonstrates the use of the `Rectangle.grid()` method to create Rectangle grids
* both with `Double` values to specify cell dimensions, and with `Int` values
* to specify cell counts.
*
* The program creates a grid of squares of side 50.0, then maps each resulting
* cell to a grid between 1 and 3 columns and rows, then discards half of
* the resulting cells by using the `List.filter { }` method.
*/
fun main() = application {
// Try changing the resolution. The design will use the available space.
configure {
Expand All @@ -25,9 +36,9 @@ fun main() = application {
// in the parent grid cells. Notice how we don't specify cell
// sizes here but counts instead (between 1 and 3 columns and
// rows)
val count = Random.int(1, 4)
val count = Int.uniform(1, 4)
rect.grid(count, count, 5.0, 5.0, 5.0, 5.0).flatten()
}.flatten().filter { Random.bool(0.5) }
}.flatten().filter { Boolean.random(0.5) }

extend {
drawer.clear(ColorRGBa.PINK)
Expand Down
23 changes: 19 additions & 4 deletions orx-shapes/src/jvmDemo/kotlin/primitives/DemoRectangleGrid03.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,26 @@ package primitives

import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.extra.color.presets.LIME_GREEN
import org.openrndr.extra.color.presets.ORANGE
import org.openrndr.extra.color.presets.YELLOW_GREEN
import org.openrndr.extra.shapes.primitives.bounds
import org.openrndr.extra.shapes.primitives.grid
import org.openrndr.extra.shapes.primitives.get
import org.openrndr.shape.bounds

/**
* Demonstrates the use of the `Rectangle`'s `get()` method,
* which can be accessed using the square bracket notation.
*
* `get()` takes two `IntRange` arguments and returns a `Rectangle`
* that covers those cell ranges.
*
* This program first creates a grid of rectangles covering the whole
* window and renders it with white borders.
*
* Next, it renders five cell ranges in different colors.
*/
fun main() = application {
configure {
width = 720
Expand All @@ -20,19 +35,19 @@ fun main() = application {
drawer.fill = null
drawer.rectangles(grid.flatten())

drawer.fill = ColorRGBa.GRAY.shade(0.4).opacify(0.5)
drawer.fill = ColorRGBa.YELLOW.shade(0.4).opacify(0.5)
drawer.rectangle(grid[1..10, 0..4].bounds)

drawer.fill = ColorRGBa.PINK.shade(0.5).opacify(0.5)
drawer.fill = ColorRGBa.MAGENTA.shade(0.5).opacify(0.5)
drawer.rectangle(grid[5..6, 1].bounds)

drawer.fill = ColorRGBa.PINK.opacify(0.5)
drawer.rectangle(grid[2..5, 2].bounds)

drawer.fill = ColorRGBa.GRAY.opacify(0.5)
drawer.fill = ColorRGBa.CYAN.opacify(0.5)
drawer.rectangle(grid[6..9, 2].bounds)

drawer.fill = ColorRGBa.GRAY.shade(0.5).opacify(0.5)
drawer.fill = ColorRGBa.LIME_GREEN.shade(0.5).opacify(0.5)
drawer.rectangle(grid[5..6, 3].bounds)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import org.openrndr.color.ColorRGBa
import org.openrndr.extra.shapes.primitives.intersection

/**
* Demonstrate rectangle-rectangle intersection
* @see <img src="https://raw.githubusercontent.com/openrndr/orx/media/orx-shapes/images/primitives-DemoRectangleIntersection01Kt.png">
* Demonstrates how to calculate a rectangle-rectangle intersection.
* @see <img src="https://raw.githubusercontent.com/openrndr/orx/media/orx-shapes/images/primitives-DemoRectangleIntersection01Kt.png" width="500">
*/
fun main() = application {
configure {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ import org.openrndr.extra.shapes.primitives.irregularGrid
import org.openrndr.extra.shapes.primitives.row
import kotlin.random.Random

/**
* Demonstrates how to use `Rectangle.irregularGrid()` to create a grid with varying column widths
* and row heights. The widths and heights are specified as a list of `Double` each.
*
* The program also demonstrates how to query a `row()` and a `column()` from a `RectangleGrid` instance,
* both of which return a `List<Rectangle>`. Both `Rectangle` lists are rendered with translucent
* colors, which makes the intersection of the column and the row slightly brighter.
*
*/
fun main() = application {
configure {
width = 720
Expand Down
12 changes: 9 additions & 3 deletions orx-shapes/src/jvmDemo/kotlin/primitives/DemoRectanglePlace01.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,20 @@ import org.openrndr.math.Vector2
import org.openrndr.shape.Rectangle

/**
* Demo for rendering a 10x10 grid of rectangles within the bounds
* of the canvas. Each rectangle's position is calculated relative to its anchors, filling the entire
* Demonstrates the use of the `Rectangle.place()` method which can be used to place rectangles
* relative to another rectangle (the drawer bounds in this case).
*
* The program renders a 10x10 grid of rectangles within the bounds of the canvas.
* Each rectangle's position is calculated relative to its anchors, filling the entire
* canvas with evenly placed items.
*
* The rectangles are drawn using the default white color. The `place` function is applied to each
* The rectangles are drawn using the default white color. The `Rectangle.place()` function is applied to each
* rectangle to position them dynamically based on their relative anchor points within the bounding area.
*
* This serves as a demonstration of positioning and rendering shapes in a structured grid layout.
*
* Note that `place()` has `anchor` and `itemAnchor` arguments.
* By default `itemAnchor` equals `anchor`.
*/
fun main() {
application {
Expand Down
17 changes: 15 additions & 2 deletions orx-shapes/src/jvmDemo/kotlin/primitives/DemoRegularPolygon.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,19 @@ import org.openrndr.extra.shapes.primitives.regularPolygon
import org.openrndr.math.map
import kotlin.math.cos

/**
* Demonstrates how to use `regularPolygon()` to create regular `ShapeContour`s.
* By specifying the number of side the program creates a triangle, a square,
* a pentagon, a hexagon, a heptagon and an octagon.
*
* The radius is animated with the cosine of time.
*
* The position is calculated by converting the shape index into columns and rows
* (using modulo and the integer division), then mapped to window coordinates.
*
* A continuous rotation is applied to all polygons for an animated effect.
*
*/
fun main() = application {
program {
extend {
Expand All @@ -15,7 +28,7 @@ fun main() = application {

for (sides in 0 until 8) {
val radius0 = cos(seconds + sides) * 20.0 + 40.0
val star = regularPolygon(sides + 3, radius = radius0)
val polygon = regularPolygon(sides + 3, radius = radius0)

drawer.isolated {
translate(
Expand All @@ -24,7 +37,7 @@ fun main() = application {
(sides / 4).toDouble().map(0.0, 1.0,
height * 0.3, height * 0.7))
rotate(seconds * 45.0)
contour(star)
contour(polygon)
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions orx-shapes/src/jvmDemo/kotlin/primitives/DemoRegularStar01.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ import org.openrndr.extra.shapes.primitives.regularStar
import kotlin.math.cos
import kotlin.math.sin

/**
* Demonstrates the use of `regularStar()` to produce a `ShapeContour`.
* The two required radii are calculated using the cosine and the sine of the time in seconds.
*
* In one brief instant, when both radii are equal, the 5-point star is rendered as a Decagon.
*
*/
fun main() = application {
program {
extend {
Expand Down
5 changes: 5 additions & 0 deletions orx-shapes/src/jvmDemo/kotlin/primitives/DemoRegularStar02.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ import org.openrndr.shape.contains
import kotlin.math.cos
import kotlin.math.sin

/**
* Demonstrates how to create a 12-point regular star, and one approach to filling
* the star with a grid of circles: testing whether various Vector2 coordinates are `in` the
* `ShapeContour` or not.
*/
fun main() = application {
program {
extend {
Expand Down
Loading