Compare commits
7 Commits
816e954ed8
...
0d15c60606
| Author | SHA1 | Date | |
|---|---|---|---|
| 0d15c60606 | |||
| ac86ab3976 | |||
|
|
3ba0395c16 | ||
|
|
10888b0e83 | ||
|
|
6024e62af0 | ||
|
|
4af2ed3fed | ||
|
|
522627ca51 |
@@ -61,6 +61,9 @@ dependencies {
|
||||
implementation(project(":orx-palette")) {
|
||||
exclude(group = "org.openrndr", module = "openrndr-draw")
|
||||
}
|
||||
implementation(project(":orx-shapes")) {
|
||||
exclude(group = "org.openrndr", module = "openrndr-draw")
|
||||
}
|
||||
|
||||
testImplementation(libs.junit)
|
||||
androidTestImplementation(libs.ext.junit)
|
||||
|
||||
@@ -9,6 +9,8 @@ import com.icegps.orx.ktx.area
|
||||
import com.icegps.orx.ktx.toColorInt
|
||||
import com.icegps.orx.ktx.toMapboxPoint
|
||||
import com.icegps.orx.ktx.toast
|
||||
import com.icegps.orx.triangulation.DelaunayTriangulation3D
|
||||
import com.icegps.orx.triangulation.Triangle3D
|
||||
import com.icegps.shared.ktx.TAG
|
||||
import com.mapbox.geojson.Feature
|
||||
import com.mapbox.geojson.FeatureCollection
|
||||
@@ -30,8 +32,7 @@ import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import com.icegps.orx.triangulation.DelaunayTriangulation3D
|
||||
import com.icegps.orx.triangulation.Triangle3D
|
||||
import org.openrndr.extra.shapes.splines.CatmullRomChain2
|
||||
import org.openrndr.math.Vector2
|
||||
import org.openrndr.math.Vector3
|
||||
import org.openrndr.shape.Rectangle
|
||||
@@ -294,10 +295,21 @@ class ContoursManager(
|
||||
style.addLayer(layer)
|
||||
}
|
||||
|
||||
private var useCatmullRom: Boolean = true
|
||||
|
||||
fun setCatmullRom(enabled: Boolean) {
|
||||
useCatmullRom = enabled
|
||||
}
|
||||
|
||||
fun contoursToLineFeatures(contours: List<ShapeContour>, color: Int): List<List<Feature>> {
|
||||
return contours.drop(1).map { contour ->
|
||||
contour.segments.map { segment ->
|
||||
LineString.fromLngLats(listOf(segment.start.toMapboxPoint(), segment.end.toMapboxPoint()))
|
||||
LineString.fromLngLats(
|
||||
listOf(
|
||||
segment.start.toMapboxPoint(),
|
||||
segment.end.toMapboxPoint()
|
||||
)
|
||||
)
|
||||
}.map { lineString ->
|
||||
Feature.fromGeometry(lineString).apply {
|
||||
// 将颜色Int转换为十六进制字符串
|
||||
@@ -311,6 +323,12 @@ class ContoursManager(
|
||||
val lists = contours.drop(0).filter { it.segments.isNotEmpty() }.map { contour ->
|
||||
val start = contour.segments[0].start
|
||||
listOf(start) + contour.segments.map { it.end }
|
||||
}.map {
|
||||
if (!useCatmullRom) return@map it
|
||||
val cmr = CatmullRomChain2(it, 1.0, loop = true)
|
||||
val contour = ShapeContour.fromPoints(cmr.positions(200), true)
|
||||
val start = contour.segments[0].start
|
||||
listOf(start) + contour.segments.map { it.end }
|
||||
}.map { points -> points.map { it.toMapboxPoint() } }
|
||||
|
||||
if (lists.isEmpty()) {
|
||||
|
||||
117
android/src/main/res/layout-port/activity_main.xml
Normal file
117
android/src/main/res/layout-port/activity_main.xml
Normal file
@@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<com.mapbox.maps.MapView
|
||||
android:id="@+id/map_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="3" />
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.slider.Slider
|
||||
android:id="@+id/slider_target_height"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:value="0"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="100" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="栅格大小:" />
|
||||
|
||||
<com.google.android.material.slider.Slider
|
||||
android:id="@+id/cell_size"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:value="1"
|
||||
android:valueFrom="1"
|
||||
android:valueTo="100" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="高度范围:" />
|
||||
|
||||
<com.google.android.material.slider.RangeSlider
|
||||
android:id="@+id/height_range"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="100" />
|
||||
</LinearLayout>
|
||||
|
||||
<Switch
|
||||
android:id="@+id/switch_grid"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:switchPadding="16dp"
|
||||
android:text="栅格网" />
|
||||
|
||||
<Switch
|
||||
android:id="@+id/switch_triangle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:switchPadding="16dp"
|
||||
android:text="三角网" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="坐标数量:" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/point_count"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/update"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="刷新界面" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/clear_points"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="清除所有点" />
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
</LinearLayout>
|
||||
@@ -132,7 +132,7 @@ abstract class CollectScreenshotsTask @Inject constructor() : DefaultTask() {
|
||||
val codeLines = ktFile.readLines()
|
||||
val main = codeLines.indexOfFirst { it.startsWith("fun main") }
|
||||
val head = codeLines.take(main)
|
||||
val start = head.indexOfLast { it.startsWith("/**") }
|
||||
val start = head.indexOfLast { it.startsWith("/*") }
|
||||
val end = head.indexOfLast { it.endsWith("*/") }
|
||||
|
||||
if ((start < end) && (end < main)) {
|
||||
|
||||
@@ -51,7 +51,12 @@ Two color spaces are added: `ColorHSLUVa` and `ColorHPLUVa`, they are an impleme
|
||||
## Demos
|
||||
### colormap/DemoSpectralZucconiColormap
|
||||
|
||||
This program demonstrates the `spectralZucconi6()` function, which
|
||||
takes a normalized value and returns a `ColorRGBa` using the
|
||||
accurate spectral colormap developed by Alan Zucconi.
|
||||
|
||||
It draws a varying number of vertical bands (between 16 and 48)
|
||||
filled with various hues.
|
||||
|
||||

|
||||
|
||||
@@ -59,7 +64,13 @@ Two color spaces are added: `ColorHSLUVa` and `ColorHPLUVa`, they are an impleme
|
||||
|
||||
### colormap/DemoSpectralZucconiColormapPhrase
|
||||
|
||||
This program demonstrates how to use the shader-based version of
|
||||
the `spectral_zucconi6()` function, which
|
||||
takes a normalized value and returns an `rgb` color using the
|
||||
accurate spectral colormap developed by Alan Zucconi.
|
||||
|
||||
It shades a full-window rectangle using its normalized `x` coordinate
|
||||
in a `ShadeStyle` to choose pixel colors.
|
||||
|
||||

|
||||
|
||||
@@ -67,7 +78,11 @@ Two color spaces are added: `ColorHSLUVa` and `ColorHPLUVa`, they are an impleme
|
||||
|
||||
### colormap/DemoSpectralZucconiColormapPlot
|
||||
|
||||
This demo uses the shader based `spectral_zucconi6()` function to fill the background,
|
||||
then visualizes the red, green and blue components of the colors used in the background
|
||||
as red, green and blue line strips.
|
||||
|
||||
The Vector2 points for the line strips are calculated only once when the program starts.
|
||||
|
||||

|
||||
|
||||
@@ -75,7 +90,12 @@ Two color spaces are added: `ColorHSLUVa` and `ColorHPLUVa`, they are an impleme
|
||||
|
||||
### colormap/DemoTurboColormap
|
||||
|
||||
This program demonstrates the `turboColormap()` function, which
|
||||
takes a normalized value and returns a `ColorRGBa` using the
|
||||
Turbo colormap developed by Google.
|
||||
|
||||
It draws a varying number of vertical bands (between 16 and 48)
|
||||
filled with various hues.
|
||||
|
||||

|
||||
|
||||
@@ -83,7 +103,13 @@ Two color spaces are added: `ColorHSLUVa` and `ColorHPLUVa`, they are an impleme
|
||||
|
||||
### colormap/DemoTurboColormapPhrase
|
||||
|
||||
This program demonstrates how to use the shader-based version of
|
||||
the `turbo_colormap()` function, which
|
||||
takes a normalized value and returns an `rgb` color using the
|
||||
Turbo colormap developed by Google.
|
||||
|
||||
It shades a full-window rectangle using its normalized `x` coordinate
|
||||
in a `ShadeStyle` to choose pixel colors.
|
||||
|
||||

|
||||
|
||||
@@ -91,7 +117,11 @@ Two color spaces are added: `ColorHSLUVa` and `ColorHPLUVa`, they are an impleme
|
||||
|
||||
### colormap/DemoTurboColormapPlot
|
||||
|
||||
This demo uses the shader based `turbo_colormap()` function to fill the background,
|
||||
then visualizes the red, green and blue components of the colors used in the background
|
||||
as red, green and blue line strips.
|
||||
|
||||
The Vector2 points for the line strips are calculated only once when the program starts.
|
||||
|
||||

|
||||
|
||||
@@ -171,7 +201,8 @@ to position the images dynamically based on their index within the grid.
|
||||
|
||||
### colorRange/DemoColorRange01
|
||||
|
||||
|
||||
Comparison of color lists generated by interpolating from
|
||||
`PINK` to `BLUE` in six different color spaces.
|
||||
|
||||

|
||||
|
||||
@@ -179,7 +210,13 @@ to position the images dynamically based on their index within the grid.
|
||||
|
||||
### colorRange/DemoColorRange02
|
||||
|
||||
Demonstrates how to create a `ColorSequence` containing three colors, one of them in the HSLUV color space.
|
||||
|
||||
Each color in the sequence is assigned a normalized position: in this program, one at the start (0.0),
|
||||
one in the middle (0.5) and one at the end (1.0).
|
||||
|
||||
The `ColorSpace.blend()` method is used to get a list with 18 interpolated `ColorRGBa` colors,
|
||||
then those colors are drawn as vertical rectangles covering the whole window.
|
||||
|
||||

|
||||
|
||||
@@ -187,7 +224,13 @@ to position the images dynamically based on their index within the grid.
|
||||
|
||||
### colorRange/DemoColorRange03
|
||||
|
||||
This program creates color interpolations from `ColorRGBa.BLUE` to
|
||||
`ColorRGBa.PINK` in 25 steps in multiple color spaces.
|
||||
|
||||
The window height is adjusted based on the number of interpolations to show.
|
||||
|
||||
The resulting gradients differ in saturation and brightness and apparently include more
|
||||
`BLUE` or more `PINK` depending on the chosen color space.
|
||||
|
||||

|
||||
|
||||
@@ -195,6 +238,17 @@ to position the images dynamically based on their index within the grid.
|
||||
|
||||
### colorRange/DemoColorRange04
|
||||
|
||||
A visualization of color interpolations inside a 3D RGB cube with an interactive 3D `Orbital` camera.
|
||||
|
||||
The hues of the source and target colors are animated over time.
|
||||
|
||||
The color interpolations are shown simultaneously in nine different color spaces, revealing how in
|
||||
each case they share common starting and ending points in 3D, but have unique paths going from
|
||||
start to end.
|
||||
|
||||
By rotating the cube 90 degrees towards the left and slightly zooming out, one can appreciate how
|
||||
one of the points moves along the edges of the cube, while the other moves on the edges of a
|
||||
smaller, invisible cube.
|
||||
|
||||
|
||||

|
||||
@@ -337,13 +391,6 @@ The rendering process includes:
|
||||
|
||||
### histogram/DemoHistogram01
|
||||
|
||||
package histogram
|
||||
|
||||
import org.openrndr.application
|
||||
import org.openrndr.draw.loadImage
|
||||
import org.openrndr.extra.color.statistics.calculateHistogramRGB
|
||||
|
||||
/*
|
||||
Demonstrates how to generate a palette with the top 32 colors
|
||||
of a loaded image, sorted by luminosity. The colors are displayed
|
||||
as rectangles overlayed on top of the image.
|
||||
@@ -354,14 +401,6 @@ as rectangles overlayed on top of the image.
|
||||
|
||||
### histogram/DemoHistogram02
|
||||
|
||||
package histogram
|
||||
|
||||
import org.openrndr.application
|
||||
import org.openrndr.draw.loadImage
|
||||
import org.openrndr.extra.color.statistics.calculateHistogramRGB
|
||||
import kotlin.math.pow
|
||||
|
||||
/*
|
||||
Show the color histogram of an image using non-uniform weighting,
|
||||
prioritizing bright colors.
|
||||
|
||||
@@ -371,13 +410,6 @@ prioritizing bright colors.
|
||||
|
||||
### histogram/DemoHistogram03
|
||||
|
||||
package histogram
|
||||
|
||||
import org.openrndr.application
|
||||
import org.openrndr.draw.loadImage
|
||||
import org.openrndr.extra.color.statistics.calculateHistogramRGB
|
||||
|
||||
/*
|
||||
Create a simple grid-like composition based on colors sampled from image.
|
||||
The cells are 32 by 32 pixels in size and are filled with a random sample
|
||||
taken from the color histogram of the image.
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package colorRange
|
||||
|
||||
// Comparison of color lists generated by interpolating from
|
||||
// PINK to BLUE in different color models
|
||||
|
||||
import org.openrndr.application
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.color.palettes.rangeTo
|
||||
@@ -11,6 +8,10 @@ import org.openrndr.math.Vector2
|
||||
import org.openrndr.math.map
|
||||
import org.openrndr.shape.Rectangle
|
||||
|
||||
/**
|
||||
* Comparison of color lists generated by interpolating from
|
||||
* `PINK` to `BLUE` in six different color spaces.
|
||||
*/
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
|
||||
@@ -1,12 +1,19 @@
|
||||
package colorRange
|
||||
|
||||
// Create a colorSequence with multiple color models
|
||||
|
||||
import org.openrndr.application
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.color.palettes.colorSequence
|
||||
import org.openrndr.extra.color.spaces.toHSLUVa
|
||||
|
||||
/**
|
||||
* Demonstrates how to create a `ColorSequence` containing three colors, one of them in the HSLUV color space.
|
||||
*
|
||||
* Each color in the sequence is assigned a normalized position: in this program, one at the start (0.0),
|
||||
* one in the middle (0.5) and one at the end (1.0).
|
||||
*
|
||||
* The `ColorSpace.blend()` method is used to get a list with 18 interpolated `ColorRGBa` colors,
|
||||
* then those colors are drawn as vertical rectangles covering the whole window.
|
||||
*/
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
@@ -14,14 +21,16 @@ fun main() = application {
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
val cs = colorSequence(0.0 to ColorRGBa.PINK,
|
||||
0.5 to ColorRGBa.BLUE,
|
||||
1.0 to ColorRGBa.PINK.toHSLUVa()) // <-- note this one is in hsluv
|
||||
val cs = colorSequence(
|
||||
0.0 to ColorRGBa.PINK,
|
||||
0.5 to ColorRGBa.BLUE,
|
||||
1.0 to ColorRGBa.PINK.toHSLUVa() // <-- note this color is in HSLUV
|
||||
)
|
||||
|
||||
for (c in cs blend (width / 40)) {
|
||||
drawer.fill = c
|
||||
drawer.stroke = null
|
||||
drawer.rectangle(0.0, 0.0, 40.0, height.toDouble())
|
||||
drawer.rectangle(0.0, 0.0, 40.0, height.toDouble())
|
||||
drawer.translate(40.0, 0.0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,36 +6,43 @@ import org.openrndr.draw.loadFont
|
||||
import org.openrndr.extra.color.palettes.rangeTo
|
||||
import org.openrndr.extra.color.spaces.*
|
||||
|
||||
/**
|
||||
* This program creates color interpolations from `ColorRGBa.BLUE` to
|
||||
* `ColorRGBa.PINK` in 25 steps in multiple color spaces.
|
||||
*
|
||||
* The window height is adjusted based on the number of interpolations to show.
|
||||
*
|
||||
* The resulting gradients differ in saturation and brightness and apparently include more
|
||||
* `BLUE` or more `PINK` depending on the chosen color space.
|
||||
*/
|
||||
fun main() = application {
|
||||
val colorA = ColorRGBa.BLUE
|
||||
val colorB = ColorRGBa.PINK
|
||||
|
||||
val stepCount = 25
|
||||
|
||||
val allSteps = listOf(
|
||||
"RGB" to (colorA..colorB blend stepCount),
|
||||
"RGB linear" to (colorA.toLinear()..colorB.toLinear() blend stepCount),
|
||||
"HSV" to (colorA..colorB.toHSVa() blend stepCount),
|
||||
"Lab" to (colorA.toLABa()..colorB.toLABa() blend stepCount),
|
||||
"LCh(ab)" to (colorA.toLCHABa()..colorB.toLCHABa() blend stepCount),
|
||||
"OKLab" to (colorA.toOKLABa()..colorB.toOKLABa() blend stepCount),
|
||||
"OKLCh" to (colorA.toOKLCHa()..colorB.toOKLCHa() blend stepCount),
|
||||
"OKHSV" to (colorA.toOKHSVa()..colorB.toOKHSVa() blend stepCount),
|
||||
"OKHSL" to (colorA.toOKHSLa()..colorB.toOKHSLa() blend stepCount),
|
||||
"HSLUV" to (colorA.toHSLUVa()..colorB.toHSLUVa() blend stepCount),
|
||||
"XSLUV" to (colorA.toXSLUVa()..colorB.toXSLUVa() blend stepCount),
|
||||
)
|
||||
|
||||
configure {
|
||||
width = 720
|
||||
height = 30 + 50 * 11 // row count
|
||||
height = 30 + 50 * allSteps.size
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.WHITE)
|
||||
|
||||
val colorA = ColorRGBa.BLUE
|
||||
val colorB = ColorRGBa.PINK
|
||||
|
||||
val stepCount = 25
|
||||
|
||||
val allSteps = listOf(
|
||||
"RGB" to (colorA..colorB blend stepCount),
|
||||
"RGB linear" to (colorA.toLinear()..colorB.toLinear() blend stepCount),
|
||||
"HSV" to (colorA..colorB.toHSVa() blend stepCount),
|
||||
"Lab" to (colorA.toLABa()..colorB.toLABa() blend stepCount),
|
||||
"LCh(ab)" to (colorA.toLCHABa()..colorB.toLCHABa() blend stepCount),
|
||||
"OKLab" to (colorA.toOKLABa()..colorB.toOKLABa() blend stepCount),
|
||||
"OKLCh" to (colorA.toOKLCHa()..colorB.toOKLCHa() blend stepCount),
|
||||
"OKHSV" to (colorA.toOKHSVa()..colorB.toOKHSVa() blend stepCount),
|
||||
"OKHSL" to (colorA.toOKHSLa()..colorB.toOKHSLa() blend stepCount),
|
||||
"HSLUV" to (colorA.toHSLUVa()..colorB.toHSLUVa() blend stepCount),
|
||||
"XSLUV" to (colorA.toXSLUVa()..colorB.toXSLUVa() blend stepCount),
|
||||
)
|
||||
|
||||
drawer.stroke = null
|
||||
|
||||
drawer.fontMap = loadFont("demo-data/fonts/IBMPlexMono-Regular.ttf", 16.0)
|
||||
drawer.translate(20.0, 20.0)
|
||||
for ((label, steps) in allSteps) {
|
||||
|
||||
@@ -14,6 +14,20 @@ import org.openrndr.extra.color.spaces.toXSLUVa
|
||||
import org.openrndr.extra.meshgenerators.sphereMesh
|
||||
import org.openrndr.math.Vector3
|
||||
|
||||
/**
|
||||
* A visualization of color interpolations inside a 3D RGB cube with an interactive 3D `Orbital` camera.
|
||||
*
|
||||
* The hues of the source and target colors are animated over time.
|
||||
*
|
||||
* The color interpolations are shown simultaneously in nine different color spaces, revealing how in
|
||||
* each case they share common starting and ending points in 3D, but have unique paths going from
|
||||
* start to end.
|
||||
*
|
||||
* By rotating the cube 90 degrees towards the left and slightly zooming out, one can appreciate how
|
||||
* one of the points moves along the edges of the cube, while the other moves on the edges of a
|
||||
* smaller, invisible cube.
|
||||
*
|
||||
*/
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
@@ -44,9 +58,6 @@ fun main() = application {
|
||||
"XSLUV" to (colorA.toXSLUVa()..colorB.toXSLUVa() blend stepCount),
|
||||
)
|
||||
|
||||
drawer.stroke = null
|
||||
|
||||
drawer.fontMap = loadFont("demo-data/fonts/IBMPlexMono-Regular.ttf", 16.0)
|
||||
for ((_, steps) in allSteps) {
|
||||
for (i in steps.indices) {
|
||||
val srgb = steps[i].toSRGB().clip()
|
||||
|
||||
@@ -5,6 +5,14 @@ import org.openrndr.extra.color.colormaps.spectralZucconi6
|
||||
import org.openrndr.extra.noise.fastFloor
|
||||
import kotlin.math.sin
|
||||
|
||||
/**
|
||||
* This program demonstrates the `spectralZucconi6()` function, which
|
||||
* takes a normalized value and returns a `ColorRGBa` using the
|
||||
* accurate spectral colormap developed by Alan Zucconi.
|
||||
*
|
||||
* It draws a varying number of vertical bands (between 16 and 48)
|
||||
* filled with various hues.
|
||||
*/
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
@@ -14,12 +22,13 @@ fun main() = application {
|
||||
extend {
|
||||
drawer.stroke = null
|
||||
val stripeCount = 32 + (sin(seconds) * 16.0).fastFloor()
|
||||
val bandWidth = width / stripeCount.toDouble()
|
||||
repeat(stripeCount) { i ->
|
||||
drawer.fill = spectralZucconi6(i / stripeCount.toDouble())
|
||||
drawer.rectangle(
|
||||
x = i * width / stripeCount.toDouble(),
|
||||
x = i * bandWidth,
|
||||
y = 0.0,
|
||||
width = width / stripeCount.toDouble(),
|
||||
width = bandWidth,
|
||||
height = height.toDouble(),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,15 @@ import org.openrndr.draw.shadeStyle
|
||||
import org.openrndr.extra.color.colormaps.ColormapPhraseBook
|
||||
import org.openrndr.extra.shaderphrases.preprocess
|
||||
|
||||
/**
|
||||
* This program demonstrates how to use the shader-based version of
|
||||
* the `spectral_zucconi6()` function, which
|
||||
* takes a normalized value and returns an `rgb` color using the
|
||||
* accurate spectral colormap developed by Alan Zucconi.
|
||||
*
|
||||
* It shades a full-window rectangle using its normalized `x` coordinate
|
||||
* in a `ShadeStyle` to choose pixel colors.
|
||||
*/
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
|
||||
@@ -8,6 +8,13 @@ import org.openrndr.extra.color.colormaps.spectralZucconi6
|
||||
import org.openrndr.extra.shaderphrases.preprocess
|
||||
import org.openrndr.math.Vector2
|
||||
|
||||
/**
|
||||
* This demo uses the shader based `spectral_zucconi6()` function to fill the background,
|
||||
* then visualizes the red, green and blue components of the colors used in the background
|
||||
* as red, green and blue line strips.
|
||||
*
|
||||
* The Vector2 points for the line strips are calculated only once when the program starts.
|
||||
*/
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
@@ -20,14 +27,14 @@ fun main() = application {
|
||||
fragmentTransform = "x_fill.rgb = spectral_zucconi6(c_boundsPosition.x);"
|
||||
}
|
||||
|
||||
// Function that expects as an argument a function to convert a ColorRGBa into a Double,
|
||||
// and returns a list of Vector2 coordinates.
|
||||
fun getColormapPoints(
|
||||
block: ColorRGBa.() -> Double
|
||||
) = List(width) { x ->
|
||||
Vector2(
|
||||
x.toDouble(),
|
||||
height.toDouble()
|
||||
- block(spectralZucconi6(x / width.toDouble()))
|
||||
* height.toDouble()
|
||||
(1.0 - block(spectralZucconi6(x / width.toDouble()))) * height
|
||||
)
|
||||
}
|
||||
|
||||
@@ -39,11 +46,13 @@ fun main() = application {
|
||||
shadeStyle = backgroundStyle
|
||||
rectangle(bounds)
|
||||
shadeStyle = null
|
||||
strokeWeight = 1.0
|
||||
|
||||
stroke = ColorRGBa.RED
|
||||
lineStrip(redPoints)
|
||||
|
||||
stroke = ColorRGBa.GREEN
|
||||
lineStrip(greenPoints)
|
||||
|
||||
stroke = ColorRGBa.BLUE
|
||||
lineStrip(bluePoints)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,15 @@ import org.openrndr.extra.color.colormaps.turboColormap
|
||||
import org.openrndr.extra.noise.fastFloor
|
||||
import kotlin.math.sin
|
||||
|
||||
/**
|
||||
* This program demonstrates the `turboColormap()` function, which
|
||||
* takes a normalized value and returns a `ColorRGBa` using the
|
||||
* Turbo colormap developed by Google.
|
||||
*
|
||||
* It draws a varying number of vertical bands (between 16 and 48)
|
||||
* filled with various hues.
|
||||
*/
|
||||
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
|
||||
@@ -5,6 +5,15 @@ import org.openrndr.draw.shadeStyle
|
||||
import org.openrndr.extra.color.colormaps.ColormapPhraseBook
|
||||
import org.openrndr.extra.shaderphrases.preprocess
|
||||
|
||||
/**
|
||||
* This program demonstrates how to use the shader-based version of
|
||||
* the `turbo_colormap()` function, which
|
||||
* takes a normalized value and returns an `rgb` color using the
|
||||
* Turbo colormap developed by Google.
|
||||
*
|
||||
* It shades a full-window rectangle using its normalized `x` coordinate
|
||||
* in a `ShadeStyle` to choose pixel colors.
|
||||
*/
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
|
||||
@@ -8,6 +8,13 @@ import org.openrndr.extra.color.colormaps.turboColormap
|
||||
import org.openrndr.extra.shaderphrases.preprocess
|
||||
import org.openrndr.math.Vector2
|
||||
|
||||
/**
|
||||
* This demo uses the shader based `turbo_colormap()` function to fill the background,
|
||||
* then visualizes the red, green and blue components of the colors used in the background
|
||||
* as red, green and blue line strips.
|
||||
*
|
||||
* The Vector2 points for the line strips are calculated only once when the program starts.
|
||||
*/
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
@@ -23,10 +30,8 @@ fun main() = application {
|
||||
block: ColorRGBa.() -> Double
|
||||
) = List(width) { x ->
|
||||
Vector2(
|
||||
x = x.toDouble(),
|
||||
y = height.toDouble()
|
||||
- block(turboColormap(x / width.toDouble()))
|
||||
* height.toDouble()
|
||||
x.toDouble(),
|
||||
(1.0 - block(turboColormap(x / width.toDouble()))) * height
|
||||
)
|
||||
}
|
||||
val redPoints = getColormapPoints { r }
|
||||
@@ -37,11 +42,13 @@ fun main() = application {
|
||||
shadeStyle = backgroundStyle
|
||||
rectangle(bounds)
|
||||
shadeStyle = null
|
||||
strokeWeight = 1.0
|
||||
|
||||
stroke = ColorRGBa.RED
|
||||
lineStrip(redPoints)
|
||||
|
||||
stroke = ColorRGBa.GREEN
|
||||
lineStrip(greenPoints)
|
||||
|
||||
stroke = ColorRGBa.BLUE
|
||||
lineStrip(bluePoints)
|
||||
}
|
||||
|
||||
@@ -26,7 +26,16 @@ this addon provides some helper functions to convert them to OPENRNDR types:
|
||||
## Demos
|
||||
### DemoContours01
|
||||
|
||||
Demonstrates how to convert a PNG image into `ShapeContour`s using BoofCV.
|
||||
|
||||
Two helper methods help convert data types between BoofCV and OPENRNDR.
|
||||
|
||||
The `ColorBuffer.toGrayF32()` method converts an OPENRNDR `ColorBuffer` to `GrayF32` format,
|
||||
required by BoofCV.
|
||||
|
||||
The `.toShapeContours()` converts BoofCV contours to OPENRNDR `ShapeContour` instances.
|
||||
|
||||
The resulting contours are animated zooming in and out while their colors change slowly.
|
||||
|
||||

|
||||
|
||||
@@ -34,7 +43,8 @@ this addon provides some helper functions to convert them to OPENRNDR types:
|
||||
|
||||
### DemoResize01
|
||||
|
||||
|
||||
Demonstrates how to scale down images using the `resizeBy` BoofCV-based
|
||||
method.
|
||||
|
||||

|
||||
|
||||
@@ -42,7 +52,11 @@ this addon provides some helper functions to convert them to OPENRNDR types:
|
||||
|
||||
### DemoResize02
|
||||
|
||||
Demonstrates how to scale down images using the `resizeTo` BoofCV-based
|
||||
method.
|
||||
|
||||
If only the `newWidth` or the `newHeight` arguments are specified,
|
||||
the resizing happens maintaining the original aspect ratio.
|
||||
|
||||

|
||||
|
||||
@@ -50,7 +64,16 @@ this addon provides some helper functions to convert them to OPENRNDR types:
|
||||
|
||||
### DemoSimplified01
|
||||
|
||||
When converting a `ColorBuffer` to `ShapeContour` instances using
|
||||
`BoofCV`, simple shapes can have hundreds of segments and vertices.
|
||||
|
||||
This demo shows how to use the `simplify()` method to greatly
|
||||
reduce the number of vertices.
|
||||
|
||||
Then it uses the simplified vertex lists to create smooth curves
|
||||
(using `CatmullRomChain2`) and polygonal curves (using `ShapeContour.fromPoints`).
|
||||
|
||||
Study the console to learn about the number of segments before and after simplification.
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -12,6 +12,18 @@ import org.openrndr.draw.loadImage
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
/**
|
||||
* Demonstrates how to convert a PNG image into `ShapeContour`s using BoofCV.
|
||||
*
|
||||
* Two helper methods help convert data types between BoofCV and OPENRNDR.
|
||||
*
|
||||
* The `ColorBuffer.toGrayF32()` method converts an OPENRNDR `ColorBuffer` to `GrayF32` format,
|
||||
* required by BoofCV.
|
||||
*
|
||||
* The `.toShapeContours()` converts BoofCV contours to OPENRNDR `ShapeContour` instances.
|
||||
*
|
||||
* The resulting contours are animated zooming in and out while their colors change slowly.
|
||||
*/
|
||||
fun main() = application {
|
||||
program {
|
||||
// Load an image, convert to BoofCV format using orx-boofcv
|
||||
|
||||
@@ -2,19 +2,31 @@ import org.openrndr.application
|
||||
import org.openrndr.boofcv.binding.resizeBy
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.draw.loadImage
|
||||
import org.openrndr.math.Vector2
|
||||
|
||||
/**
|
||||
* Demonstrates how to scale down images using the `resizeBy` BoofCV-based
|
||||
* method.
|
||||
*/
|
||||
fun main() = application {
|
||||
program {
|
||||
// Load an image, convert to BoofCV format using orx-boofcv
|
||||
val input = loadImage("demo-data/images/image-001.png")
|
||||
|
||||
val scaled = input.resizeBy(0.5)
|
||||
val scaled2 = input.resizeBy(0.25, convertToGray = true)
|
||||
val scaled3 = input.resizeBy(0.1)
|
||||
|
||||
println("${input.width} x ${input.height}")
|
||||
println("${scaled.width} x ${scaled.height}")
|
||||
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
drawer.translate(0.0, (height - scaled.bounds.height) / 2.0)
|
||||
|
||||
// Display the loaded image to the right of `scaled` matching its size
|
||||
drawer.image(input, scaled.bounds.movedBy(Vector2.UNIT_X * scaled.bounds.width))
|
||||
|
||||
// Display actually scaled down versions of the loaded image
|
||||
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,17 +3,29 @@ import org.openrndr.boofcv.binding.resizeTo
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.draw.loadImage
|
||||
|
||||
/**
|
||||
* Demonstrates how to scale down images using the `resizeTo` BoofCV-based
|
||||
* method.
|
||||
*
|
||||
* If only the `newWidth` or the `newHeight` arguments are specified,
|
||||
* the resizing happens maintaining the original aspect ratio.
|
||||
*/
|
||||
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)
|
||||
|
||||
println("${input.width} x ${input.height}")
|
||||
println("${scaled.width} x ${scaled.height}")
|
||||
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
drawer.translate(0.0, (height - scaled.bounds.height) / 2.0)
|
||||
|
||||
// Display actually scaled down versions of the loaded image
|
||||
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,6 +17,18 @@ import org.openrndr.math.Vector2
|
||||
import org.openrndr.shape.Rectangle
|
||||
import org.openrndr.shape.ShapeContour
|
||||
|
||||
/**
|
||||
* When converting a `ColorBuffer` to `ShapeContour` instances using
|
||||
* `BoofCV`, simple shapes can have hundreds of segments and vertices.
|
||||
*
|
||||
* This demo shows how to use the `simplify()` method to greatly
|
||||
* reduce the number of vertices.
|
||||
*
|
||||
* Then it uses the simplified vertex lists to create smooth curves
|
||||
* (using `CatmullRomChain2`) and polygonal curves (using `ShapeContour.fromPoints`).
|
||||
*
|
||||
* Study the console to learn about the number of segments before and after simplification.
|
||||
*/
|
||||
fun main() = application {
|
||||
program {
|
||||
// Create a buffer where to draw something for boofcv
|
||||
@@ -41,6 +53,7 @@ fun main() = application {
|
||||
rectangle(0.0, -200.0, 60.0, 60.0)
|
||||
circle(0.0, 190.0, 60.0)
|
||||
}
|
||||
|
||||
// Convert the bitmap buffer into ShapeContours
|
||||
val vectorized = imageToContours(rt.colorBuffer(0))
|
||||
|
||||
@@ -73,8 +86,11 @@ fun main() = application {
|
||||
extend {
|
||||
drawer.run {
|
||||
fill = null // ColorRGBa.PINK.opacify(0.15)
|
||||
|
||||
stroke = ColorRGBa.PINK.opacify(0.7)
|
||||
contours(polygonal)
|
||||
|
||||
stroke = ColorRGBa.GREEN.opacify(0.7)
|
||||
contours(smooth)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,7 +178,10 @@ import org.openrndr.extra.parameters.DoubleParameter
|
||||
## Demos
|
||||
### DemoAppearance01
|
||||
|
||||
A simple demonstration of a GUI for drawing some circles
|
||||
Demonstrates how to customize the appearance of the GUI by using
|
||||
`GUIAppearance()`.
|
||||
|
||||
In this demo, we make the GUI wider (400 pixels) and translucent.
|
||||
|
||||

|
||||
|
||||
@@ -186,7 +189,7 @@ A simple demonstration of a GUI for drawing some circles
|
||||
|
||||
### DemoHide01
|
||||
|
||||
A simple demonstration of a GUI for drawing some circles
|
||||
Demonstrates how to hide the GUI when the mouse pointer is outside of it.
|
||||
|
||||

|
||||
|
||||
@@ -194,15 +197,38 @@ A simple demonstration of a GUI for drawing some circles
|
||||
|
||||
### DemoOptions01
|
||||
|
||||
A simple demonstration of a GUI with a drop down menu
|
||||
A simple demonstration of a GUI with a drop-down menu.
|
||||
|
||||
The entries in the drop-down menu are taken from an `enum class`.
|
||||
|
||||

|
||||
|
||||
[source code](src/demo/kotlin/DemoOptions01.kt)
|
||||
|
||||
### DemoOptions02
|
||||
|
||||
A simple demonstration of a GUI with a drop-down menu.
|
||||
|
||||
The entries in the drop-down menu are taken from an `enum class`.
|
||||
The `enum class` entries contain both a name (used in the drop-down)
|
||||
and a `ColorRGBa` instance (used for rendering).
|
||||
|
||||

|
||||
|
||||
[source code](src/demo/kotlin/DemoOptions02.kt)
|
||||
|
||||
### DemoPath01
|
||||
|
||||
Demonstrates how to include a button for loading images in a GUI, and how to display
|
||||
the loaded image.
|
||||
|
||||
The program applies the `@PathParameter` annotation to a `String` variable, which gets
|
||||
rendered by the GUI as an image-picker button. Note the allowed file `extensions`.
|
||||
|
||||
This mechanism only updates the `String` containing the path of an image file.
|
||||
|
||||
The `watchingImagePath()` delegate property is used to automatically load an image
|
||||
when its `String` argument changes.
|
||||
|
||||

|
||||
|
||||
@@ -210,9 +236,11 @@ A simple demonstration of a GUI with a drop down menu
|
||||
|
||||
### DemoPresets01
|
||||
|
||||
Shows how to store and retrieve in-memory gui presets.
|
||||
Shows how to store and retrieve in-memory GUI presets,
|
||||
each containing two integer values and two colors.
|
||||
|
||||
Keyboard controls:
|
||||
[Left Shift] + [0]..[9] => store current gui values to a preset
|
||||
[Left Shift] + [0]..[9] => store current GUI values to a preset
|
||||
[0]..[9] => recall a preset
|
||||
|
||||

|
||||
@@ -221,7 +249,17 @@ Keyboard controls:
|
||||
|
||||
### DemoSideCanvas01
|
||||
|
||||
A simple demonstration of a GUI for drawing some circles
|
||||
Demonstrates the `GUI.enableSideCanvas` feature.
|
||||
|
||||
When set to true, the `GUI` provides a `canvas` property where one can draw.
|
||||
The size of this canvas is the window size minus the GUI size.
|
||||
|
||||
That's why if we draw a circle at `drawer.width / 2.0` it is centered
|
||||
on the `canvas`, not on the window.
|
||||
|
||||
This demo sets the window to resizable, so if you resize the window
|
||||
you should see tha the circle stays at the center of the canvas.
|
||||
|
||||
|
||||

|
||||
|
||||
@@ -229,7 +267,15 @@ A simple demonstration of a GUI for drawing some circles
|
||||
|
||||
### DemoSimple01
|
||||
|
||||
A simple demonstration of a GUI for drawing some circles
|
||||
Demonstrates how to create a simple GUI with 4 inputs:
|
||||
- A `ColorParameter` which creates a color picker.
|
||||
- A `DoubleParameter` to control the radius of a circle.
|
||||
- A `Vector2Parameter` to set the position of that circle.
|
||||
- A `DoubleListParameter` which sets the radii of six circles.
|
||||
|
||||
The demo also shows how to use the variables controlled by the GUI
|
||||
inside the program, so changes to those variables affect
|
||||
the rendering in real time.
|
||||
|
||||

|
||||
|
||||
@@ -237,6 +283,10 @@ A simple demonstration of a GUI for drawing some circles
|
||||
|
||||
### DemoXYParameter
|
||||
|
||||
Demonstrates the use of the `@XYParameter` annotation applied to a `Vector2` variable.
|
||||
|
||||
This annotation creates an interactive XY control in a GUI that can be used to update
|
||||
a `Vector2` variable. In this demo it sets the position of a circle.
|
||||
|
||||
|
||||

|
||||
|
||||
@@ -7,7 +7,10 @@ import org.openrndr.math.Vector2
|
||||
import org.openrndr.shape.Circle
|
||||
|
||||
/**
|
||||
* A simple demonstration of a GUI for drawing some circles
|
||||
* Demonstrates how to customize the appearance of the GUI by using
|
||||
* `GUIAppearance()`.
|
||||
*
|
||||
* In this demo, we make the GUI wider (400 pixels) and translucent.
|
||||
*/
|
||||
fun main() = application {
|
||||
program {
|
||||
|
||||
@@ -6,7 +6,7 @@ import org.openrndr.math.Vector2
|
||||
import org.openrndr.shape.Circle
|
||||
|
||||
/**
|
||||
* A simple demonstration of a GUI for drawing some circles
|
||||
* Demonstrates how to hide the GUI when the mouse pointer is outside of it.
|
||||
*/
|
||||
fun main() = application {
|
||||
program {
|
||||
@@ -29,7 +29,7 @@ fun main() = application {
|
||||
gui.add(settings)
|
||||
extend(gui)
|
||||
|
||||
// note we can only change the visibility after the extend
|
||||
// note we can only change the visibility after the `extend`
|
||||
gui.visible = false
|
||||
|
||||
extend {
|
||||
|
||||
@@ -6,7 +6,7 @@ import org.openrndr.window
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
/**
|
||||
* Demonstration of multi window GUI in the manual way
|
||||
* Demonstration of a multi window GUI in the manual way
|
||||
*/
|
||||
fun main() {
|
||||
// skip this demo on CI
|
||||
|
||||
@@ -4,7 +4,7 @@ import org.openrndr.extra.parameters.DoubleParameter
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
/**
|
||||
* Demonstration of multi window GUI using WindowedGUI extension
|
||||
* Demonstration of a multi window GUI using the `WindowedGUI` extension
|
||||
*/
|
||||
fun main() {
|
||||
// skip this demo on CI
|
||||
|
||||
@@ -5,7 +5,9 @@ import org.openrndr.extra.parameters.Description
|
||||
import org.openrndr.extra.parameters.OptionParameter
|
||||
|
||||
/**
|
||||
* A simple demonstration of a GUI with a drop down menu
|
||||
* A simple demonstration of a GUI with a drop-down menu.
|
||||
*
|
||||
* The entries in the drop-down menu are taken from an `enum class`.
|
||||
*/
|
||||
|
||||
enum class BackgroundColors {
|
||||
@@ -15,6 +17,10 @@ enum class BackgroundColors {
|
||||
}
|
||||
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 360
|
||||
}
|
||||
program {
|
||||
val gui = GUI()
|
||||
gui.compartmentsCollapsedByDefault = false
|
||||
|
||||
43
orx-jvm/orx-gui/src/demo/kotlin/DemoOptions02.kt
Normal file
43
orx-jvm/orx-gui/src/demo/kotlin/DemoOptions02.kt
Normal file
@@ -0,0 +1,43 @@
|
||||
import org.openrndr.application
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.gui.GUI
|
||||
import org.openrndr.extra.parameters.Description
|
||||
import org.openrndr.extra.parameters.OptionParameter
|
||||
|
||||
/**
|
||||
* A simple demonstration of a GUI with a drop-down menu.
|
||||
*
|
||||
* The entries in the drop-down menu are taken from an `enum class`.
|
||||
* The `enum class` entries contain both a name (used in the drop-down)
|
||||
* and a `ColorRGBa` instance (used for rendering).
|
||||
*/
|
||||
|
||||
enum class BackgroundColors2(val color: ColorRGBa) {
|
||||
Pink(ColorRGBa.PINK),
|
||||
Black(ColorRGBa.BLACK),
|
||||
Yellow(ColorRGBa.YELLOW)
|
||||
}
|
||||
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 360
|
||||
}
|
||||
program {
|
||||
val gui = GUI()
|
||||
gui.compartmentsCollapsedByDefault = false
|
||||
val settings = @Description("Settings") object {
|
||||
@OptionParameter("Background color")
|
||||
var option = BackgroundColors2.Pink
|
||||
}
|
||||
|
||||
gui.add(settings)
|
||||
extend(gui)
|
||||
gui.onChange { name, value ->
|
||||
println("$name: $value")
|
||||
}
|
||||
extend {
|
||||
drawer.clear(settings.option.color)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,18 @@ import org.openrndr.extra.parameters.Description
|
||||
import org.openrndr.extra.parameters.PathParameter
|
||||
import org.openrndr.extra.propertywatchers.watchingImagePath
|
||||
|
||||
/**
|
||||
* Demonstrates how to include a button for loading images in a GUI, and how to display
|
||||
* the loaded image.
|
||||
*
|
||||
* The program applies the `@PathParameter` annotation to a `String` variable, which gets
|
||||
* rendered by the GUI as an image-picker button. Note the allowed file `extensions`.
|
||||
*
|
||||
* This mechanism only updates the `String` containing the path of an image file.
|
||||
*
|
||||
* The `watchingImagePath()` delegate property is used to automatically load an image
|
||||
* when its `String` argument changes.
|
||||
*/
|
||||
fun main() = application {
|
||||
program {
|
||||
val gui = GUI()
|
||||
|
||||
@@ -7,12 +7,18 @@ import org.openrndr.extra.parameters.Description
|
||||
import org.openrndr.extra.parameters.IntParameter
|
||||
|
||||
/**
|
||||
* Shows how to store and retrieve in-memory gui presets.
|
||||
* Shows how to store and retrieve in-memory GUI presets,
|
||||
* each containing two integer values and two colors.
|
||||
*
|
||||
* Keyboard controls:
|
||||
* [Left Shift] + [0]..[9] => store current gui values to a preset
|
||||
* [Left Shift] + [0]..[9] => store current GUI values to a preset
|
||||
* [0]..[9] => recall a preset
|
||||
*/
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 480
|
||||
}
|
||||
program {
|
||||
val gui = GUI()
|
||||
gui.compartmentsCollapsedByDefault = false
|
||||
@@ -43,9 +49,9 @@ fun main() = application {
|
||||
// Draw a pattern based on modulo
|
||||
for (i in 0 until 100) {
|
||||
if (i % settings.a == 0 || i % settings.b == 0) {
|
||||
val x = (i % 10) * 64.0
|
||||
val x = (i % 10) * 72.0
|
||||
val y = (i / 10) * 48.0
|
||||
drawer.rectangle(x, y, 64.0, 48.0)
|
||||
drawer.rectangle(x, y, 72.0, 48.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,18 +2,29 @@ import org.openrndr.application
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.gui.GUI
|
||||
import org.openrndr.extra.gui.GUIAppearance
|
||||
import org.openrndr.extra.parameters.*
|
||||
import org.openrndr.math.Vector2
|
||||
import org.openrndr.extra.parameters.ColorParameter
|
||||
import org.openrndr.extra.parameters.Description
|
||||
import org.openrndr.extra.parameters.DoubleParameter
|
||||
import org.openrndr.panel.elements.draw
|
||||
|
||||
|
||||
/**
|
||||
* A simple demonstration of a GUI for drawing some circles
|
||||
* Demonstrates the `GUI.enableSideCanvas` feature.
|
||||
*
|
||||
* When set to true, the `GUI` provides a `canvas` property where one can draw.
|
||||
* The size of this canvas is the window size minus the GUI size.
|
||||
*
|
||||
* That's why if we draw a circle at `drawer.width / 2.0` it is centered
|
||||
* on the `canvas`, not on the window.
|
||||
*
|
||||
* This demo sets the window to resizable, so if you resize the window
|
||||
* you should see tha the circle stays at the center of the canvas.
|
||||
*
|
||||
*/
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 800
|
||||
height = 800
|
||||
width = 720
|
||||
height = 720
|
||||
windowResizable = true
|
||||
}
|
||||
|
||||
@@ -23,17 +34,11 @@ fun main() = application {
|
||||
gui.enableSideCanvas = true
|
||||
|
||||
val settings = @Description("Settings") object {
|
||||
@DoubleParameter("radius", 0.0, 100.0)
|
||||
@DoubleParameter("radius", 0.0, 200.0)
|
||||
var radius = 50.0
|
||||
|
||||
@Vector2Parameter("position", 0.0, 1.0)
|
||||
var position = Vector2(0.6, 0.5)
|
||||
|
||||
@ColorParameter("color")
|
||||
var color = ColorRGBa.PINK
|
||||
|
||||
@DoubleListParameter("radii", 5.0, 30.0)
|
||||
var radii = mutableListOf(5.0, 6.0, 8.0, 14.0, 20.0, 30.0)
|
||||
}
|
||||
gui.add(settings)
|
||||
extend(gui)
|
||||
@@ -42,7 +47,7 @@ fun main() = application {
|
||||
val width = drawer.width
|
||||
val height = drawer.height
|
||||
drawer.fill = settings.color
|
||||
drawer.circle(width/2.0, height/2.0, 100.0)
|
||||
drawer.circle(width / 2.0, height / 2.0, settings.radius)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,11 +6,22 @@ import org.openrndr.math.Vector2
|
||||
import org.openrndr.shape.Circle
|
||||
|
||||
/**
|
||||
* A simple demonstration of a GUI for drawing some circles
|
||||
* Demonstrates how to create a simple GUI with 4 inputs:
|
||||
* - A `ColorParameter` which creates a color picker.
|
||||
* - A `DoubleParameter` to control the radius of a circle.
|
||||
* - A `Vector2Parameter` to set the position of that circle.
|
||||
* - A `DoubleListParameter` which sets the radii of six circles.
|
||||
*
|
||||
* The demo also shows how to use the variables controlled by the GUI
|
||||
* inside the program, so changes to those variables affect
|
||||
* the rendering in real time.
|
||||
*/
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 450
|
||||
}
|
||||
program {
|
||||
|
||||
val gui = GUI()
|
||||
gui.compartmentsCollapsedByDefault = false
|
||||
|
||||
|
||||
@@ -4,6 +4,13 @@ import org.openrndr.extra.parameters.Description
|
||||
import org.openrndr.extra.parameters.XYParameter
|
||||
import org.openrndr.math.Vector2
|
||||
|
||||
/**
|
||||
* Demonstrates the use of the `@XYParameter` annotation applied to a `Vector2` variable.
|
||||
*
|
||||
* This annotation creates an interactive XY control in a GUI that can be used to update
|
||||
* a `Vector2` variable. In this demo it sets the position of a circle.
|
||||
*
|
||||
*/
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 800
|
||||
|
||||
@@ -42,7 +42,15 @@ More info about the web client:
|
||||
## Demos
|
||||
### DemoRabbitControl
|
||||
|
||||
Demonstrates how to use RabbitControl to create a web-based user interface for your program.
|
||||
|
||||
A `settings` object is created using the same syntax used for `orx-gui`, including
|
||||
annotations for different variable types.
|
||||
|
||||
The program then passes these `settings` to the `RabbitControlServer`. A QR-code is displayed
|
||||
to open the web user interface. A clickable URL is also displayed in the console.
|
||||
|
||||
Once the UI is visible in a web browser we can use it to control the OPENRNDR program.
|
||||
|
||||

|
||||
|
||||
@@ -50,7 +58,10 @@ More info about the web client:
|
||||
|
||||
### DemoRabbitControlManualOverlay
|
||||
|
||||
Demonstrates how the QR-code pointing at the Rabbit Control web-based user interface
|
||||
can be displayed and hidden manually.
|
||||
|
||||
To display the QR-code overlay in this demo, hold down the HOME key in the keyboard.
|
||||
|
||||

|
||||
|
||||
@@ -58,6 +69,12 @@ More info about the web client:
|
||||
|
||||
### DemoRabbitHole
|
||||
|
||||
Starts the RabbitControlServer with a `Rabbithole` using the key 'orxtest'.
|
||||
|
||||
`Rabbithole` allows you to access your exposed parameters from Internet
|
||||
connected computers that are not in the same network.
|
||||
|
||||
To use it with this example use 'orxtest' as the tunnel-name in https://rabbithole.rabbitcontrol.cc
|
||||
|
||||
|
||||

|
||||
|
||||
@@ -6,7 +6,17 @@ import org.openrndr.math.Vector2
|
||||
import org.openrndr.math.Vector3
|
||||
import org.openrndr.math.Vector4
|
||||
|
||||
|
||||
/**
|
||||
* Demonstrates how to use RabbitControl to create a web-based user interface for your program.
|
||||
*
|
||||
* A `settings` object is created using the same syntax used for `orx-gui`, including
|
||||
* annotations for different variable types.
|
||||
*
|
||||
* The program then passes these `settings` to the `RabbitControlServer`. A QR-code is displayed
|
||||
* to open the web user interface. A clickable URL is also displayed in the console.
|
||||
*
|
||||
* Once the UI is visible in a web browser we can use it to control the OPENRNDR program.
|
||||
*/
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 800
|
||||
|
||||
@@ -4,6 +4,12 @@ import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.parameters.BooleanParameter
|
||||
|
||||
|
||||
/**
|
||||
* Demonstrates how the QR-code pointing at the Rabbit Control web-based user interface
|
||||
* can be displayed and hidden manually.
|
||||
*
|
||||
* To display the QR-code overlay in this demo, hold down the HOME key in the keyboard.
|
||||
*/
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 800
|
||||
|
||||
@@ -6,7 +6,15 @@ import org.openrndr.math.Vector2
|
||||
import org.openrndr.math.Vector3
|
||||
import org.openrndr.math.Vector4
|
||||
|
||||
|
||||
/**
|
||||
* Starts the RabbitControlServer with a `Rabbithole` using the key 'orxtest'.
|
||||
*
|
||||
* `Rabbithole` allows you to access your exposed parameters from Internet
|
||||
* connected computers that are not in the same network.
|
||||
*
|
||||
* To use it with this example use 'orxtest' as the tunnel-name in https://rabbithole.rabbitcontrol.cc
|
||||
*
|
||||
*/
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 800
|
||||
@@ -14,13 +22,6 @@ fun main() = application {
|
||||
}
|
||||
|
||||
program {
|
||||
/**
|
||||
* Start RabbitControlServer with a Rabbithole with key 'orxtest'
|
||||
* Please visit https://rabbithole.rabbitcontrol.cc for more information.
|
||||
*
|
||||
* Rabbithole allows you to access your exposed parameter from the internet.
|
||||
* To use it with this example just use 'orxtest' as tunnel-name on the main page.
|
||||
*/
|
||||
val rabbit = RabbitControlServer(false, 10000, 8080, "wss://rabbithole.rabbitcontrol.cc/public/rcpserver/connect?key=orxtest")
|
||||
val font = loadFont("demo-data/fonts/IBMPlexMono-Regular.ttf", 20.0)
|
||||
val settings = object {
|
||||
|
||||
@@ -105,7 +105,15 @@ Demonstrate decal generation and rendering
|
||||
|
||||
### DemoAll
|
||||
|
||||
Demonstrates how to create various types of 3D meshes:
|
||||
box, sphere, dodecahedron, cylinder, plane, cap and resolve.
|
||||
|
||||
Two textures are used: one generative with gradients, and the second
|
||||
one is an image loaded from disk. The horizontal mouse position is used
|
||||
to select which of the two textures to use.
|
||||
|
||||
The meshes are positioned in space using a 2D mesh, and displayed
|
||||
rotating on the X and Y axes at different speeds.
|
||||
|
||||

|
||||
|
||||
@@ -113,6 +121,18 @@ Demonstrate decal generation and rendering
|
||||
|
||||
### DemoBox
|
||||
|
||||
Demonstrates how to create a 3D mesh box by specifying its width, height and depth.
|
||||
|
||||
The `box` is a `VertexBuffer` and contains texture coordinates which can be
|
||||
used to apply a texture to its faces.
|
||||
|
||||
After creating the box, the program creates a texture with a gradient.
|
||||
In it, the red component increases along the x-axis and the green component
|
||||
along the y-axis.
|
||||
|
||||
The scene is rendered with an interactive `Orbital` 3D camera.
|
||||
|
||||
A shade style is used to apply the texture to the box.
|
||||
|
||||
|
||||

|
||||
@@ -121,7 +141,15 @@ Demonstrate decal generation and rendering
|
||||
|
||||
### DemoComplex01
|
||||
|
||||
Demonstrates how to use `buildTriangleMesh` to construct composite 3D meshes.
|
||||
|
||||
A DSL allows specifying the color and transformations of each mesh, in this case,
|
||||
of a sphere and a box.
|
||||
|
||||
An interactive 3D Orbital camera is defined, specifying the location of its `eye` and
|
||||
`lookAt` properties.
|
||||
|
||||
A minimal shade style is used to simulate a uni-directional light pointing along the view Z axis.
|
||||
|
||||

|
||||
|
||||
@@ -129,7 +157,7 @@ Demonstrate decal generation and rendering
|
||||
|
||||
### DemoComplex02
|
||||
|
||||
|
||||
Demonstrates the creation of a 3D mesh composed of two hemispheres, a cylinder and 12 legs.
|
||||
|
||||

|
||||
|
||||
@@ -137,7 +165,14 @@ Demonstrate decal generation and rendering
|
||||
|
||||
### DemoComplex03
|
||||
|
||||
Demonstrates the creation of a 3D mesh composed of two hemispheres, a cylinder and 12 legs.
|
||||
Additionally, the body of the shape features 5 ridges on the sides
|
||||
of the cylinder.
|
||||
|
||||
The code reveals DSL keywords under `buildTriangleMesh`
|
||||
affecting transformation matrices, for instance `isolated`, `translate` and `rotate`,
|
||||
and mesh generating keywords like
|
||||
`hemisphere`, `taperedCylinder` and `cylinder`.
|
||||
|
||||

|
||||
|
||||
@@ -145,7 +180,9 @@ Demonstrate decal generation and rendering
|
||||
|
||||
### DemoComplex04
|
||||
|
||||
|
||||
Demonstrates the use of `buildTriangleMesh` to create
|
||||
a composite 3D mesh and introduces a new mesh generating keyword:
|
||||
`cap`.
|
||||
|
||||

|
||||
|
||||
@@ -153,6 +190,9 @@ Demonstrate decal generation and rendering
|
||||
|
||||
### DemoComplex05
|
||||
|
||||
Demonstrates how to create a 3D grid of extruded shapes
|
||||
(short cylinders), then applies three 3D twists to the
|
||||
composition to deform it.
|
||||
|
||||
|
||||

|
||||
@@ -161,8 +201,11 @@ Demonstrate decal generation and rendering
|
||||
|
||||
### DemoComplex06
|
||||
|
||||
Generates a grid of grids of boxes.
|
||||
Interactive orbital camera.
|
||||
Generates a grid of grids of 3D boxes using `buildTriangleMesh` and
|
||||
renders them using an interactive orbital camera.
|
||||
|
||||
The cubes ar colorized using a shade style that sets colors based
|
||||
on vertex positions in space, converting XYZ coordinates into RGB colors.
|
||||
|
||||
|
||||

|
||||
@@ -270,7 +313,13 @@ for a radial-symmetry effect.
|
||||
|
||||
### tangents/DemoTangents01
|
||||
|
||||
Tangent and bitangent vectors are used in shader programs for tangent space normal mapping / lighting
|
||||
and certain forms of displacement mapping.
|
||||
|
||||
This demo shows:
|
||||
- how to create a triangulated `MeshData`.
|
||||
- how to estimate the tangents of this MeshData.
|
||||
- How to use the tangent and bitangent attributes in GLSL code.
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -8,6 +8,17 @@ import org.openrndr.math.Vector2
|
||||
import org.openrndr.math.Vector3
|
||||
import org.openrndr.shape.Rectangle
|
||||
|
||||
/**
|
||||
* Demonstrates how to create various types of 3D meshes:
|
||||
* box, sphere, dodecahedron, cylinder, plane, cap and resolve.
|
||||
*
|
||||
* Two textures are used: one generative with gradients, and the second
|
||||
* one is an image loaded from disk. The horizontal mouse position is used
|
||||
* to select which of the two textures to use.
|
||||
*
|
||||
* The meshes are positioned in space using a 2D mesh, and displayed
|
||||
* rotating on the X and Y axes at different speeds.
|
||||
*/
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
|
||||
@@ -9,6 +9,21 @@ import org.openrndr.extra.camera.Orbital
|
||||
import org.openrndr.extra.meshgenerators.boxMesh
|
||||
import org.openrndr.math.Vector3
|
||||
|
||||
/**
|
||||
* Demonstrates how to create a 3D mesh box by specifying its width, height and depth.
|
||||
*
|
||||
* The `box` is a `VertexBuffer` and contains texture coordinates which can be
|
||||
* used to apply a texture to its faces.
|
||||
*
|
||||
* After creating the box, the program creates a texture with a gradient.
|
||||
* In it, the red component increases along the x-axis and the green component
|
||||
* along the y-axis.
|
||||
*
|
||||
* The scene is rendered with an interactive `Orbital` 3D camera.
|
||||
*
|
||||
* A shade style is used to apply the texture to the box.
|
||||
*
|
||||
*/
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
|
||||
@@ -9,6 +9,17 @@ import org.openrndr.extra.meshgenerators.buildTriangleMesh
|
||||
import org.openrndr.extra.meshgenerators.sphere
|
||||
import org.openrndr.math.Vector3
|
||||
|
||||
/**
|
||||
* Demonstrates how to use `buildTriangleMesh` to construct composite 3D meshes.
|
||||
*
|
||||
* A DSL allows specifying the color and transformations of each mesh, in this case,
|
||||
* of a sphere and a box.
|
||||
*
|
||||
* An interactive 3D Orbital camera is defined, specifying the location of its `eye` and
|
||||
* `lookAt` properties.
|
||||
*
|
||||
* A minimal shade style is used to simulate a uni-directional light pointing along the view Z axis.
|
||||
*/
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
|
||||
@@ -8,6 +8,9 @@ import org.openrndr.extra.meshgenerators.cylinder
|
||||
import org.openrndr.extra.meshgenerators.hemisphere
|
||||
import org.openrndr.math.Vector3
|
||||
|
||||
/**
|
||||
* Demonstrates the creation of a 3D mesh composed of two hemispheres, a cylinder and 12 legs.
|
||||
*/
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
|
||||
@@ -6,6 +6,16 @@ import org.openrndr.extra.camera.Orbital
|
||||
import org.openrndr.extra.meshgenerators.*
|
||||
import org.openrndr.math.Vector3
|
||||
|
||||
/**
|
||||
* Demonstrates the creation of a 3D mesh composed of two hemispheres, a cylinder and 12 legs.
|
||||
* Additionally, the body of the shape features 5 ridges on the sides
|
||||
* of the cylinder.
|
||||
*
|
||||
* The code reveals DSL keywords under `buildTriangleMesh`
|
||||
* affecting transformation matrices, for instance `isolated`, `translate` and `rotate`,
|
||||
* and mesh generating keywords like
|
||||
* `hemisphere`, `taperedCylinder` and `cylinder`.
|
||||
*/
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
|
||||
@@ -7,6 +7,11 @@ import org.openrndr.extra.meshgenerators.*
|
||||
import org.openrndr.math.Vector2
|
||||
import org.openrndr.math.Vector3
|
||||
|
||||
/**
|
||||
* Demonstrates the use of `buildTriangleMesh` to create
|
||||
* a composite 3D mesh and introduces a new mesh generating keyword:
|
||||
* `cap`.
|
||||
*/
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
|
||||
@@ -11,6 +11,12 @@ import org.openrndr.extra.meshgenerators.twist
|
||||
import org.openrndr.math.Vector3
|
||||
import org.openrndr.shape.Circle
|
||||
|
||||
/**
|
||||
* Demonstrates how to create a 3D grid of extruded shapes
|
||||
* (short cylinders), then applies three 3D twists to the
|
||||
* composition to deform it.
|
||||
*
|
||||
*/
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
|
||||
@@ -9,8 +9,11 @@ import org.openrndr.extra.noise.simplex
|
||||
import org.openrndr.math.Vector3
|
||||
|
||||
/**
|
||||
* Generates a grid of grids of boxes.
|
||||
* Interactive orbital camera.
|
||||
* Generates a grid of grids of 3D boxes using `buildTriangleMesh` and
|
||||
* renders them using an interactive orbital camera.
|
||||
*
|
||||
* The cubes ar colorized using a shade style that sets colors based
|
||||
* on vertex positions in space, converting XYZ coordinates into RGB colors.
|
||||
*
|
||||
*/
|
||||
fun main() = application {
|
||||
|
||||
@@ -10,6 +10,15 @@ import org.openrndr.extra.objloader.loadOBJMeshData
|
||||
import org.openrndr.math.Vector3
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Tangent and bitangent vectors are used in shader programs for tangent space normal mapping / lighting
|
||||
* and certain forms of displacement mapping.
|
||||
*
|
||||
* This demo shows:
|
||||
* - how to create a triangulated `MeshData`.
|
||||
* - how to estimate the tangents of this MeshData.
|
||||
* - How to use the tangent and bitangent attributes in GLSL code.
|
||||
*/
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
@@ -29,12 +38,11 @@ fun main() = application {
|
||||
fragmentTransform = """
|
||||
vec3 viewTangent = (u_viewNormalMatrix * u_modelNormalMatrix * vec4(va_tangent, 0.0)).xyz;
|
||||
vec3 viewBitangent = (u_viewNormalMatrix * u_modelNormalMatrix * vec4(va_bitangent, 0.0)).xyz;
|
||||
float c = cos(100.0*dot(v_worldPosition, va_normal)) * 0.5 + 0.5;
|
||||
float c = cos(100.0 * dot(v_worldPosition, va_normal)) * 0.5 + 0.5;
|
||||
|
||||
//x_fill.rgb = normalize(viewTangent)*0.5+0.5;
|
||||
x_fill.rgb = vec3(c);
|
||||
""".trimIndent()
|
||||
|
||||
//x_fill.rgb = normalize(viewTangent) * 0.5 + 0.5;
|
||||
x_fill.rgb = vec3(c);
|
||||
""".trimIndent()
|
||||
}
|
||||
|
||||
drawer.vertexBuffer(objVB, DrawPrimitive.TRIANGLES)
|
||||
|
||||
@@ -465,6 +465,31 @@ to round contours with linear segments.
|
||||
|
||||
[source code](src/jvmDemo/kotlin/hobbycurve/DemoHobbyCurve03.kt)
|
||||
|
||||
### hobbycurve/DemoHobbyCurve04
|
||||
|
||||
Demonstrates the use of the `tensions` argument when creating a Hobby curve.
|
||||
|
||||
The program starts by creating a random set of scattered points with enough separation between them.
|
||||
The points are sorted using `hilbertOrder` to minimize the travel distance when visiting all the points.
|
||||
Finally, we draw a set of 40 hobby translucent curves using those same points but with varying tensions.
|
||||
|
||||

|
||||
|
||||
[source code](src/jvmDemo/kotlin/hobbycurve/DemoHobbyCurve04.kt)
|
||||
|
||||
### hobbycurve/DemoHobbyCurve05
|
||||
|
||||
Demonstrates the creation of a 40 hobby curves with 10 points each.
|
||||
The control points in all hobby curves are almost identical, varying only
|
||||
due to a slight increase in one of the arguments of a simplex noise call.
|
||||
|
||||
The program shows that minor displacements in control points can have
|
||||
a large impact in the resulting curve.
|
||||
|
||||

|
||||
|
||||
[source code](src/jvmDemo/kotlin/hobbycurve/DemoHobbyCurve05.kt)
|
||||
|
||||
### hobbycurve/DemoHobbyCurve3D01
|
||||
|
||||
Demonstrates how to use the 3D implementation of the `hobbyCurve` method, to draw a smooth curve passing
|
||||
@@ -678,6 +703,22 @@ Demonstrate rectangle-rectangle intersection
|
||||
|
||||
[source code](src/jvmDemo/kotlin/primitives/DemoRectangleIntersection01.kt)
|
||||
|
||||
### primitives/DemoRectangleIrregularGrid02
|
||||
|
||||
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 13 `Double` values, each
|
||||
picked randomly between the values 1.0 and 4.0. This produces two types of columns and two
|
||||
types of rows only: wide ones and narrow ones.
|
||||
|
||||
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.
|
||||
|
||||
|
||||

|
||||
|
||||
[source code](src/jvmDemo/kotlin/primitives/DemoRectangleIrregularGrid02.kt)
|
||||
|
||||
### primitives/DemoRectangleIrregularGrid
|
||||
|
||||
|
||||
@@ -749,6 +790,21 @@ This serves as a demonstration of positioning and rendering shapes in a structur
|
||||
|
||||
[source code](src/jvmDemo/kotlin/primitives/DemoTear01.kt)
|
||||
|
||||
### primitives/DemoTear02
|
||||
|
||||
Demonstrates the use of `Tear()` to create drop-like shapes out of a Vector2 point and a Circle.
|
||||
|
||||
The tear locations are calculated using the `Rectangle.scatter()` function. Locations near the
|
||||
center of the window are filtered out.
|
||||
|
||||
The radii of each tear is randomly chosen between three values. The orientation of each tear
|
||||
is calculated by getting the normalized difference between the tear and the center of the window,
|
||||
making them look as being emitted at the center of the window.
|
||||
|
||||

|
||||
|
||||
[source code](src/jvmDemo/kotlin/primitives/DemoTear02.kt)
|
||||
|
||||
### rectify/DemoRectifiedContour01
|
||||
|
||||
|
||||
|
||||
38
orx-shapes/src/jvmDemo/kotlin/hobbycurve/DemoHobbyCurve04.kt
Normal file
38
orx-shapes/src/jvmDemo/kotlin/hobbycurve/DemoHobbyCurve04.kt
Normal file
@@ -0,0 +1,38 @@
|
||||
package hobbycurve
|
||||
|
||||
import org.openrndr.application
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.noise.scatter
|
||||
import org.openrndr.extra.shapes.hobbycurve.hobbyCurve
|
||||
import org.openrndr.extra.shapes.ordering.hilbertOrder
|
||||
import kotlin.random.Random
|
||||
|
||||
/**
|
||||
* Demonstrates the use of the `tensions` argument when creating a Hobby curve.
|
||||
*
|
||||
* The program starts by creating a random set of scattered points with enough separation between them.
|
||||
* The points are sorted using `hilbertOrder` to minimize the travel distance when visiting all the points.
|
||||
* Finally, we draw a set of 40 hobby translucent curves using those same points but with varying tensions.
|
||||
*/
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
for (i in -20..20) {
|
||||
val t = i / 10.0
|
||||
val points = drawer.bounds.offsetEdges(-50.0)
|
||||
.scatter(25.0, random = Random(0))
|
||||
.hilbertOrder()
|
||||
|
||||
drawer.stroke = ColorRGBa.WHITE.opacify(0.5)
|
||||
drawer.fill = null
|
||||
drawer.contour(hobbyCurve(points, closed = false, tensions = { i, inAngle, outAngle ->
|
||||
Pair(t, t)
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
38
orx-shapes/src/jvmDemo/kotlin/hobbycurve/DemoHobbyCurve05.kt
Normal file
38
orx-shapes/src/jvmDemo/kotlin/hobbycurve/DemoHobbyCurve05.kt
Normal file
@@ -0,0 +1,38 @@
|
||||
package hobbycurve
|
||||
|
||||
import org.openrndr.application
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.color.presets.WHITE_SMOKE
|
||||
import org.openrndr.extra.noise.simplex
|
||||
import org.openrndr.extra.noise.uniform
|
||||
import org.openrndr.extra.shapes.hobbycurve.hobbyCurve
|
||||
import org.openrndr.extra.shapes.ordering.hilbertOrder
|
||||
import org.openrndr.math.Vector2
|
||||
|
||||
/**
|
||||
* Demonstrates the creation of a 40 hobby curves with 10 points each.
|
||||
* The control points in all hobby curves are almost identical, varying only
|
||||
* due to a slight increase in one of the arguments of a simplex noise call.
|
||||
*
|
||||
* The program shows that minor displacements in control points can have
|
||||
* a large impact in the resulting curve.
|
||||
*/
|
||||
fun main() = application {
|
||||
program {
|
||||
val seed = 68040
|
||||
val curves = List(40) { n ->
|
||||
hobbyCurve(List(10) {
|
||||
Vector2(
|
||||
simplex(seed, it * 13.3, n * 0.001) * 300.0 + 320.0,
|
||||
simplex(seed / 2, it * 77.4, n * 0.001) * 300.0 + 240.0
|
||||
)
|
||||
}.hilbertOrder(), true)
|
||||
}
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.WHITE_SMOKE)
|
||||
drawer.fill = null
|
||||
drawer.stroke = ColorRGBa.BLACK.opacify(0.3)
|
||||
drawer.contours(curves)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package primitives
|
||||
|
||||
import org.openrndr.application
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.color.presets.CORAL
|
||||
import org.openrndr.extra.shapes.primitives.column
|
||||
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 13 `Double` values, each
|
||||
* picked randomly between the values 1.0 and 4.0. This produces two types of columns and two
|
||||
* types of rows only: wide ones and narrow ones.
|
||||
*
|
||||
* 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
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
val r = Random(100)
|
||||
val grid = drawer.bounds.irregularGrid(
|
||||
List(13) { listOf(1.0, 4.0).random(r) },
|
||||
List(13) { listOf(1.0, 4.0).random(r) }
|
||||
)
|
||||
|
||||
drawer.fill = null
|
||||
drawer.stroke = ColorRGBa.WHITE
|
||||
drawer.rectangles(grid.flatten())
|
||||
|
||||
drawer.stroke = ColorRGBa.BLACK
|
||||
drawer.fill = ColorRGBa.PINK.opacify(0.5)
|
||||
drawer.rectangles(grid.column(2))
|
||||
|
||||
drawer.fill = ColorRGBa.CORAL.opacify(0.5)
|
||||
drawer.rectangles(grid.row(6))
|
||||
}
|
||||
}
|
||||
}
|
||||
42
orx-shapes/src/jvmDemo/kotlin/primitives/DemoTear02.kt
Normal file
42
orx-shapes/src/jvmDemo/kotlin/primitives/DemoTear02.kt
Normal file
@@ -0,0 +1,42 @@
|
||||
package primitives
|
||||
|
||||
import org.openrndr.application
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.noise.scatter
|
||||
import org.openrndr.extra.shapes.primitives.Tear
|
||||
import org.openrndr.shape.Circle
|
||||
|
||||
/**
|
||||
* Demonstrates the use of `Tear()` to create drop-like shapes out of a Vector2 point and a Circle.
|
||||
*
|
||||
* The tear locations are calculated using the `Rectangle.scatter()` function. Locations near the
|
||||
* center of the window are filtered out.
|
||||
*
|
||||
* The radii of each tear is randomly chosen between three values. The orientation of each tear
|
||||
* is calculated by getting the normalized difference between the tear and the center of the window,
|
||||
* making them look as being emitted at the center of the window.
|
||||
*/
|
||||
fun main() = application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val points = drawer.bounds.scatter(40.0, distanceToEdge = 80.0).filter {
|
||||
it.distanceTo(drawer.bounds.center) > 80.0
|
||||
}
|
||||
|
||||
val tears = points.map {
|
||||
val radius = listOf(5.0, 10.0, 20.0).random()
|
||||
val offset = (it - drawer.bounds.center).normalized * radius
|
||||
Tear(it - offset, Circle(it + offset, radius))
|
||||
}
|
||||
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.WHITE)
|
||||
drawer.fill = ColorRGBa.PINK
|
||||
drawer.stroke = ColorRGBa.BLACK
|
||||
drawer.contours(tears.map { it.contour })
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,11 @@ Note that drawing inside the `repeat` action has no effect. Have a look at the d
|
||||
## Demos
|
||||
### DemoRepeat01
|
||||
|
||||
A simple demonstration on using the `repeat` method to execute a function
|
||||
at regular intervals.
|
||||
|
||||
Note that drawing inside the repeat action has no effect.
|
||||
See DemoRepeat02.kt to learn how to trigger drawing.
|
||||
|
||||
|
||||

|
||||
@@ -45,14 +50,29 @@ Note that drawing inside the `repeat` action has no effect. Have a look at the d
|
||||
|
||||
### DemoRepeat02
|
||||
|
||||
This demonstrates how to combine `repeat {}` with a postponed event to trigger drawing
|
||||
This demonstrates how to combine `repeat {}` with a postponed event to trigger drawing.
|
||||
|
||||

|
||||
|
||||
[source code](src/demo/kotlin/DemoRepeat02.kt)
|
||||
|
||||
### DemoRepeat03
|
||||
|
||||
Shows how a `repeat` block can update a variable used
|
||||
for rendering. In this demo, the `opacity` variable is
|
||||
reduced on every animation frame, and increased to 1.0
|
||||
every 2 seconds, creating a pulsating animation effect.
|
||||
|
||||

|
||||
|
||||
[source code](src/demo/kotlin/DemoRepeat03.kt)
|
||||
|
||||
### DemoTimeOut01
|
||||
|
||||
Demonstrates the `timeOut` function.
|
||||
|
||||
It is similar to the `repeat` function,
|
||||
but it runs only once after the specified delay in seconds.
|
||||
|
||||
|
||||

|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
import org.openrndr.application
|
||||
import org.openrndr.extra.timer.repeat
|
||||
|
||||
/**
|
||||
* A simple demonstration on using the `repeat` method to execute a function
|
||||
* at regular intervals.
|
||||
*
|
||||
* Note that drawing inside the repeat action has no effect.
|
||||
* See DemoRepeat02.kt to learn how to trigger drawing.
|
||||
*
|
||||
*/
|
||||
fun main() = application {
|
||||
program {
|
||||
repeat(2.0) {
|
||||
|
||||
@@ -4,7 +4,7 @@ import org.openrndr.events.Event
|
||||
import org.openrndr.extra.timer.repeat
|
||||
|
||||
/**
|
||||
* This demonstrates how to combine `repeat {}` with a postponed event to trigger drawing
|
||||
* This demonstrates how to combine `repeat {}` with a postponed event to trigger drawing.
|
||||
*/
|
||||
|
||||
fun main() = application {
|
||||
|
||||
25
orx-timer/src/demo/kotlin/DemoRepeat03.kt
Normal file
25
orx-timer/src/demo/kotlin/DemoRepeat03.kt
Normal file
@@ -0,0 +1,25 @@
|
||||
import org.openrndr.application
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.timer.repeat
|
||||
|
||||
/**
|
||||
* Shows how a `repeat` block can update a variable used
|
||||
* for rendering. In this demo, the `opacity` variable is
|
||||
* reduced on every animation frame, and increased to 1.0
|
||||
* every 2 seconds, creating a pulsating animation effect.
|
||||
*/
|
||||
fun main() = application {
|
||||
program {
|
||||
var opacity = 0.0
|
||||
repeat(2.0) {
|
||||
opacity = 1.0
|
||||
}
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
drawer.stroke = ColorRGBa.BLACK.opacify(opacity)
|
||||
drawer.fill = ColorRGBa.WHITE.opacify(opacity)
|
||||
drawer.circle(width / 2.0, height / 2.0, 200.0)
|
||||
opacity *= 0.9
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,13 @@
|
||||
import org.openrndr.application
|
||||
import org.openrndr.extra.timer.timeOut
|
||||
|
||||
/**
|
||||
* Demonstrates the `timeOut` function.
|
||||
*
|
||||
* It is similar to the `repeat` function,
|
||||
* but it runs only once after the specified delay in seconds.
|
||||
*
|
||||
*/
|
||||
fun main() = application {
|
||||
program {
|
||||
timeOut(2.0) {
|
||||
|
||||
@@ -35,7 +35,6 @@ The language also holds some tools to manage the position and orientation of the
|
||||
## Demos
|
||||
### DemoTurtle01
|
||||
|
||||
/*
|
||||
Drawing a square using the turtle interface.
|
||||
|
||||

|
||||
@@ -44,7 +43,6 @@ Drawing a square using the turtle interface.
|
||||
|
||||
### DemoTurtle02
|
||||
|
||||
/*
|
||||
A simple random walk made using the turtle interface.
|
||||
|
||||

|
||||
@@ -53,7 +51,6 @@ A simple random walk made using the turtle interface.
|
||||
|
||||
### DemoTurtle03
|
||||
|
||||
/*
|
||||
Drawing shape contours aligned to the turtle's orientation.
|
||||
|
||||

|
||||
|
||||
Reference in New Issue
Block a user