[orx-shapes] Add Arc, Net, Pulley, Tear and bounds tools
This commit is contained in:
33
orx-shapes/src/commonMain/kotlin/Arc.kt
Normal file
33
orx-shapes/src/commonMain/kotlin/Arc.kt
Normal file
@@ -0,0 +1,33 @@
|
||||
package org.openrndr.extra.shapes
|
||||
|
||||
import org.openrndr.math.*
|
||||
import org.openrndr.shape.ShapeContour
|
||||
import org.openrndr.shape.contour
|
||||
|
||||
/**
|
||||
* A circular arc
|
||||
*/
|
||||
class Arc(val center: Vector2, val radius: Double, val angle0: Double, val angle1: Double) : LinearType<Arc> {
|
||||
fun position(t: Double): Vector2 {
|
||||
val angle = mix(angle0, angle1, t.clamp(0.0, 1.0))
|
||||
return Polar(angle, radius).cartesian + center
|
||||
}
|
||||
|
||||
val contour: ShapeContour
|
||||
get() {
|
||||
return contour {
|
||||
moveTo(position(0.0))
|
||||
circularArcTo(position(0.5), position(1.0))
|
||||
}
|
||||
}
|
||||
|
||||
override fun div(scale: Double) = Arc(center / scale, radius / scale, angle0 / scale, angle1 / scale)
|
||||
|
||||
override fun times(scale: Double) = Arc(center * scale, radius * scale, angle0 * scale, angle1 * scale)
|
||||
|
||||
override fun plus(right: Arc) =
|
||||
Arc(center + right.center, radius + right.radius, angle0 + right.angle0, angle1 + right.angle1)
|
||||
|
||||
override fun minus(right: Arc) =
|
||||
Arc(center - right.center, radius - right.radius, angle0 - right.angle0, angle1 - right.angle1)
|
||||
}
|
||||
33
orx-shapes/src/commonMain/kotlin/Net.kt
Normal file
33
orx-shapes/src/commonMain/kotlin/Net.kt
Normal file
@@ -0,0 +1,33 @@
|
||||
package org.openrndr.extra.shapes
|
||||
|
||||
import org.openrndr.math.LinearType
|
||||
import org.openrndr.math.Polar
|
||||
import org.openrndr.math.Vector2
|
||||
import org.openrndr.shape.Circle
|
||||
import org.openrndr.shape.LineSegment
|
||||
import org.openrndr.shape.ShapeContour
|
||||
|
||||
class Net(val point0: Vector2, val point1: Vector2, val circle: Circle) : LinearType<Net> {
|
||||
override fun div(scale: Double) = Net(point0 / scale, point1 / scale, circle / scale)
|
||||
|
||||
override fun times(scale: Double) = Net(point0 * scale, point1 * scale, circle * scale)
|
||||
|
||||
override fun plus(right: Net) = Net(point0 + right.point0, point1 + right.point1, circle + right.circle)
|
||||
|
||||
override fun minus(right: Net) = Net(point0 - right.point0, point1 - right.point1, circle - right.circle)
|
||||
|
||||
val contour: ShapeContour
|
||||
get() {
|
||||
val tangents0 = circle.tangents(point0)
|
||||
val tangents1 = circle.tangents(point1)
|
||||
var k = LineSegment(point0, tangents0.first).contour
|
||||
run {
|
||||
val th0 = Polar.fromVector(tangents0.first - circle.center).theta
|
||||
var th1 = Polar.fromVector(tangents1.second - circle.center).theta
|
||||
if (th1 < th0) th1 += 360.0
|
||||
k += Arc(circle.center, circle.radius, th0, th1).contour
|
||||
}
|
||||
k += LineSegment(tangents1.second, point1).contour
|
||||
return k
|
||||
}
|
||||
}
|
||||
50
orx-shapes/src/commonMain/kotlin/Pulley.kt
Normal file
50
orx-shapes/src/commonMain/kotlin/Pulley.kt
Normal file
@@ -0,0 +1,50 @@
|
||||
package org.openrndr.extra.shapes
|
||||
|
||||
import org.openrndr.math.LinearType
|
||||
import org.openrndr.math.Polar
|
||||
import org.openrndr.shape.Circle
|
||||
import org.openrndr.shape.LineSegment
|
||||
import org.openrndr.shape.ShapeContour
|
||||
|
||||
class Pulley(val circle0: Circle, val circle1: Circle) : LinearType<Pulley> {
|
||||
override fun div(scale: Double): Pulley {
|
||||
return Pulley(circle0 / scale, circle1 / scale)
|
||||
}
|
||||
|
||||
override fun times(scale: Double): Pulley {
|
||||
return Pulley(circle0 * scale, circle1 * scale)
|
||||
}
|
||||
|
||||
override fun plus(right: Pulley): Pulley {
|
||||
return Pulley(circle0 + right.circle0, circle1 + right.circle1)
|
||||
}
|
||||
|
||||
override fun minus(right: Pulley): Pulley {
|
||||
return Pulley(circle0 - right.circle0, circle1 - right.circle1)
|
||||
}
|
||||
|
||||
val contour: ShapeContour
|
||||
get() {
|
||||
val tangents = circle0.tangents(circle1)
|
||||
if (tangents.isEmpty()) {
|
||||
return ShapeContour.EMPTY
|
||||
} else {
|
||||
var k = LineSegment(tangents[0].first, tangents[0].second).contour
|
||||
|
||||
run {
|
||||
var th0 = Polar.fromVector(tangents[0].second - circle1.center).theta
|
||||
val th1 = Polar.fromVector(tangents[1].second - circle1.center).theta
|
||||
if (th0 < th1) th0 += 360.0
|
||||
k += Arc(circle1.center, circle1.radius, th0, th1).contour
|
||||
}
|
||||
k += LineSegment(tangents[1].first, tangents[1].second).contour.reversed
|
||||
run {
|
||||
val th0 = Polar.fromVector(tangents[0].first - circle0.center).theta
|
||||
var th1 = Polar.fromVector(tangents[1].first - circle0.center).theta
|
||||
if (th0 > th1) th1 += 360.0
|
||||
k += Arc(circle0.center, circle0.radius, th0, th1).contour.reversed
|
||||
}
|
||||
return k.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
32
orx-shapes/src/commonMain/kotlin/Tear.kt
Normal file
32
orx-shapes/src/commonMain/kotlin/Tear.kt
Normal file
@@ -0,0 +1,32 @@
|
||||
package org.openrndr.extra.shapes
|
||||
|
||||
import org.openrndr.math.LinearType
|
||||
import org.openrndr.math.Polar
|
||||
import org.openrndr.math.Vector2
|
||||
import org.openrndr.shape.Circle
|
||||
import org.openrndr.shape.LineSegment
|
||||
import org.openrndr.shape.ShapeContour
|
||||
|
||||
class Tear(val point: Vector2, val circle: Circle) : LinearType<Tear> {
|
||||
override fun div(scale: Double) = Tear(point / scale, circle / scale)
|
||||
|
||||
override fun times(scale: Double) = Tear(point * scale, circle * scale)
|
||||
|
||||
override fun plus(right: Tear) = Tear(point + right.point, circle + right.circle)
|
||||
|
||||
override fun minus(right: Tear) = Tear(point - right.point, circle - right.circle)
|
||||
|
||||
val contour: ShapeContour
|
||||
get() {
|
||||
val tangents = circle.tangents(point)
|
||||
var k = LineSegment(point, tangents.first).contour
|
||||
run {
|
||||
val th0 = Polar.fromVector(tangents.first - circle.center).theta
|
||||
var th1 = Polar.fromVector(tangents.second - circle.center).theta
|
||||
if (th1 < th0) th1 += 360.0
|
||||
k += Arc(circle.center, circle.radius, th0, th1).contour
|
||||
}
|
||||
k += LineSegment(tangents.second, point).contour
|
||||
return k.close()
|
||||
}
|
||||
}
|
||||
33
orx-shapes/src/commonMain/kotlin/bounds/Bounds.kt
Normal file
33
orx-shapes/src/commonMain/kotlin/bounds/Bounds.kt
Normal file
@@ -0,0 +1,33 @@
|
||||
package org.openrndr.extra.shapes.bounds
|
||||
|
||||
import org.openrndr.shape.*
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
/**
|
||||
* Evaluates the bounds around all [ShapeContour] instances in the [Iterable]
|
||||
*/
|
||||
|
||||
val Iterable<ShapeContour>.bounds : Rectangle
|
||||
@JvmName("shapeContourBounds")
|
||||
get() = map {
|
||||
it.bounds
|
||||
}.bounds
|
||||
|
||||
/**
|
||||
* Evaluates the bounds around all [Shape] instances in the [Iterable]
|
||||
*/
|
||||
val Iterable<Shape>.bounds : Rectangle
|
||||
@JvmName("shapeBounds")
|
||||
get() = map {
|
||||
it.bounds
|
||||
}.bounds
|
||||
|
||||
|
||||
/**
|
||||
* Evaluates the bounds around all [Segment] instances in the [Iterable]
|
||||
*/
|
||||
val Iterable<Segment>.bounds : Rectangle
|
||||
@JvmName("segmentBounds")
|
||||
get() = map {
|
||||
it.bounds
|
||||
}.bounds
|
||||
22
orx-shapes/src/jvmDemo/kotlin/DemoArc01.kt
Normal file
22
orx-shapes/src/jvmDemo/kotlin/DemoArc01.kt
Normal file
@@ -0,0 +1,22 @@
|
||||
import org.openrndr.application
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.shapes.Arc
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
val a = Arc(drawer.bounds.center, 100.0, 0.0 + seconds * 36.0, -180.0 + seconds * 36.0)
|
||||
drawer.clear(ColorRGBa.PINK)
|
||||
drawer.contour(a.contour)
|
||||
drawer.circle(a.position(0.0), 5.0)
|
||||
drawer.circle(a.position(0.5), 5.0)
|
||||
drawer.circle(a.position(1.0), 5.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
26
orx-shapes/src/jvmDemo/kotlin/DemoPulley01.kt
Normal file
26
orx-shapes/src/jvmDemo/kotlin/DemoPulley01.kt
Normal file
@@ -0,0 +1,26 @@
|
||||
import org.openrndr.application
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.shapes.Pulley
|
||||
import org.openrndr.math.Vector2
|
||||
import org.openrndr.shape.Circle
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
drawer.stroke = ColorRGBa.WHITE
|
||||
drawer.fill = ColorRGBa.PINK
|
||||
val pulley = Pulley(
|
||||
Circle(drawer.bounds.center - Vector2(100.0, 100.0), 150.0),
|
||||
Circle(drawer.bounds.center + Vector2(150.0, 150.0), 75.0)
|
||||
)
|
||||
drawer.contour(pulley.contour)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
29
orx-shapes/src/jvmDemo/kotlin/DemoTear01.kt
Normal file
29
orx-shapes/src/jvmDemo/kotlin/DemoTear01.kt
Normal file
@@ -0,0 +1,29 @@
|
||||
import org.openrndr.application
|
||||
import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.extra.noise.scatter
|
||||
import org.openrndr.extra.shapes.Tear
|
||||
import org.openrndr.math.Vector2
|
||||
import org.openrndr.shape.Circle
|
||||
import kotlin.random.Random
|
||||
|
||||
fun main() {
|
||||
application {
|
||||
configure {
|
||||
width = 720
|
||||
height = 720
|
||||
}
|
||||
program {
|
||||
val points = drawer.bounds.scatter(40.0, distanceToEdge = 150.0, random = Random(0))
|
||||
val tears = points.map {
|
||||
Tear(it - Vector2(0.0, 20.0), Circle(it + Vector2(0.0, 20.0), 20.0))
|
||||
}
|
||||
|
||||
extend {
|
||||
drawer.clear(ColorRGBa.BLACK)
|
||||
drawer.fill = ColorRGBa.PINK
|
||||
drawer.stroke = ColorRGBa.WHITE
|
||||
drawer.contours(tears.map { it.contour })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user