[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