[orx-shapes] Add WIP ContourAdjuster framework
This commit is contained in:
28
orx-shapes/src/commonMain/kotlin/utilities/FromContours.kt
Normal file
28
orx-shapes/src/commonMain/kotlin/utilities/FromContours.kt
Normal file
@@ -0,0 +1,28 @@
|
||||
package org.openrndr.extra.shapes.utilities
|
||||
|
||||
import org.openrndr.shape.ShapeContour
|
||||
import org.openrndr.shape.contour
|
||||
|
||||
/**
|
||||
* Create a contour from a list of contours
|
||||
*/
|
||||
fun ShapeContour.Companion.fromContours(contours: List<ShapeContour>, closed: Boolean, connectEpsilon:Double=1E-6) : ShapeContour {
|
||||
val contours = contours.filter { !it.empty }
|
||||
if (contours.isEmpty()) {
|
||||
return EMPTY
|
||||
}
|
||||
return contour {
|
||||
moveTo(contours.first().position(0.0))
|
||||
for (c in contours.windowed(2,1,true)) {
|
||||
copy(c[0])
|
||||
if (c.size == 2) {
|
||||
if (c[0].position(1.0).distanceTo(c[1].position(0.0)) > connectEpsilon ) {
|
||||
lineTo(c[1].position(0.0))
|
||||
}
|
||||
}
|
||||
}
|
||||
if (closed) {
|
||||
close()
|
||||
}
|
||||
}
|
||||
}
|
||||
35
orx-shapes/src/commonMain/kotlin/utilities/InsertPoint.kt
Normal file
35
orx-shapes/src/commonMain/kotlin/utilities/InsertPoint.kt
Normal file
@@ -0,0 +1,35 @@
|
||||
package org.openrndr.extra.shapes.utilities
|
||||
|
||||
import org.openrndr.shape.ShapeContour
|
||||
|
||||
/**
|
||||
* Insert point at [t]
|
||||
* @param ascendingTs a list of ascending T values
|
||||
* @param weldEpsilon minimum distance between T values
|
||||
*/
|
||||
fun ShapeContour.insertPointAt(t: Double, weldEpsilon: Double = 1E-6): ShapeContour {
|
||||
val splitContours = splitAt(listOf(t), weldEpsilon)
|
||||
return ShapeContour.fromContours(splitContours, closed)
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert point at [segmentIndex], [segmentT]
|
||||
* @param weldEpsilon minimum distance between T values
|
||||
*/
|
||||
fun ShapeContour.insertPointAt(segmentIndex: Int, segmentT: Double, weldEpsilon: Double = 1E-6): ShapeContour {
|
||||
val t = (1.0 / segments.size) * (segmentIndex + segmentT)
|
||||
val splitContours = splitAt(listOf(t), weldEpsilon)
|
||||
|
||||
return ShapeContour.fromContours(splitContours, closed)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Insert points at [ascendingTs]
|
||||
* @param ascendingTs a list of ascending T values
|
||||
* @param weldEpsilon minimum distance between T values
|
||||
*/
|
||||
fun ShapeContour.insertPointsAt(ascendingTs: List<Double>, weldEpsilon:Double = 1E-6) : ShapeContour {
|
||||
val splitContours = splitAt(ascendingTs, weldEpsilon)
|
||||
return ShapeContour.fromContours(splitContours, closed)
|
||||
}
|
||||
30
orx-shapes/src/commonMain/kotlin/utilities/SplitAt.kt
Normal file
30
orx-shapes/src/commonMain/kotlin/utilities/SplitAt.kt
Normal file
@@ -0,0 +1,30 @@
|
||||
package org.openrndr.extra.shapes.utilities
|
||||
|
||||
import org.openrndr.shape.Segment
|
||||
import org.openrndr.shape.ShapeContour
|
||||
|
||||
fun ShapeContour.splitAt(segmentIndex: Double, segmentT: Double): List<ShapeContour> {
|
||||
val t = (1.0 / segments.size) * (segmentIndex + segmentT)
|
||||
return splitAt(listOf(t))
|
||||
}
|
||||
|
||||
fun ShapeContour.splitAt(ascendingTs: List<Double>, weldEpsilon: Double = 1E-6): List<ShapeContour> {
|
||||
if (empty || ascendingTs.isEmpty()) {
|
||||
return listOf(this)
|
||||
}
|
||||
@Suppress("NAME_SHADOWING") val ascendingTs = (listOf(0.0) + ascendingTs + listOf(1.0)).weldAscending(weldEpsilon)
|
||||
return ascendingTs.windowed(2, 1).map {
|
||||
sub(it[0], it[1])
|
||||
}
|
||||
}
|
||||
|
||||
fun Segment.splitAt(ascendingTs: List<Double>, weldEpsilon: Double = 1E-6): List<Segment> {
|
||||
if (ascendingTs.isEmpty()) {
|
||||
return listOf(this)
|
||||
}
|
||||
|
||||
@Suppress("NAME_SHADOWING") val ascendingTs = (listOf(0.0) + ascendingTs + listOf(1.0)).weldAscending(weldEpsilon)
|
||||
return ascendingTs.windowed(2, 1).map {
|
||||
sub(it[0], it[1])
|
||||
}
|
||||
}
|
||||
21
orx-shapes/src/commonMain/kotlin/utilities/WeldAscending.kt
Normal file
21
orx-shapes/src/commonMain/kotlin/utilities/WeldAscending.kt
Normal file
@@ -0,0 +1,21 @@
|
||||
package org.openrndr.extra.shapes.utilities
|
||||
|
||||
/**
|
||||
* Weld values if their distance is less than [epsilon]
|
||||
*/
|
||||
fun List<Double>.weldAscending(epsilon: Double = 1E-6): List<Double> {
|
||||
return if (size <= 1) {
|
||||
this
|
||||
} else {
|
||||
val result = mutableListOf(first())
|
||||
var lastPassed = first()
|
||||
for (i in 1 until size) {
|
||||
require(this[i] >= lastPassed) { "input list is not in ascending order" }
|
||||
if (this[i] - lastPassed > epsilon) {
|
||||
result.add(this[i])
|
||||
lastPassed = this[i]
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user