Update for OPENRNDR segment and path generalizations
This commit is contained in:
31
orx-shapes/src/commonMain/kotlin/utilities/FromPaths.kt
Normal file
31
orx-shapes/src/commonMain/kotlin/utilities/FromPaths.kt
Normal file
@@ -0,0 +1,31 @@
|
||||
package org.openrndr.extra.shapes.utilities
|
||||
|
||||
import org.openrndr.shape.Path3D
|
||||
import org.openrndr.shape.ShapeContour
|
||||
import org.openrndr.shape.contour
|
||||
import org.openrndr.shape.path3D
|
||||
|
||||
/**
|
||||
* Create a [Path3D] from a list of paths
|
||||
*/
|
||||
fun Path3D.Companion.fromPaths(contours: List<Path3D>, closed: Boolean, connectEpsilon:Double=1E-6) : Path3D {
|
||||
@Suppress("NAME_SHADOWING") val contours = contours.filter { !it.empty }
|
||||
if (contours.isEmpty()) {
|
||||
return EMPTY
|
||||
}
|
||||
return path3D {
|
||||
moveTo(contours.first().position(0.0))
|
||||
for (c in contours.windowed(2,1,true)) {
|
||||
copy(c[0])
|
||||
if (c.size == 2) {
|
||||
val d = c[0].position(1.0).distanceTo(c[1].position(0.0))
|
||||
if (d > connectEpsilon ) {
|
||||
lineTo(c[1].position(0.0))
|
||||
}
|
||||
}
|
||||
}
|
||||
if (closed) {
|
||||
close()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,20 @@
|
||||
package org.openrndr.extra.shapes.utilities
|
||||
|
||||
import org.openrndr.shape.Segment
|
||||
import org.openrndr.shape.ShapeContour
|
||||
import org.openrndr.math.EuclideanVector
|
||||
import org.openrndr.shape.*
|
||||
|
||||
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> {
|
||||
fun Path3D.splitAt(segmentIndex: Double, segmentT: Double): List<Path3D> {
|
||||
val t = (1.0 / segments.size) * (segmentIndex + segmentT)
|
||||
return splitAt(listOf(t))
|
||||
}
|
||||
|
||||
|
||||
fun <T : EuclideanVector<T>> Path<T>.splitAtBase(ascendingTs: List<Double>, weldEpsilon: Double = 1E-6): List<Path<T>> {
|
||||
if (empty || ascendingTs.isEmpty()) {
|
||||
return listOf(this)
|
||||
}
|
||||
@@ -18,7 +24,20 @@ fun ShapeContour.splitAt(ascendingTs: List<Double>, weldEpsilon: Double = 1E-6):
|
||||
}
|
||||
}
|
||||
|
||||
fun Segment.splitAt(ascendingTs: List<Double>, weldEpsilon: Double = 1E-6): List<Segment> {
|
||||
fun ShapeContour.splitAt(ascendingTs: List<Double>, weldEpsilon: Double = 1E-6): List<ShapeContour> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return splitAtBase(ascendingTs, weldEpsilon) as List<ShapeContour>
|
||||
}
|
||||
|
||||
fun Path3D.splitAt(ascendingTs: List<Double>, weldEpsilon: Double = 1E-6): List<Path3D> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return splitAtBase(ascendingTs, weldEpsilon) as List<Path3D>
|
||||
}
|
||||
|
||||
fun <T : EuclideanVector<T>> BezierSegment<T>.splitAtBase(
|
||||
ascendingTs: List<Double>,
|
||||
weldEpsilon: Double = 1E-6
|
||||
): List<BezierSegment<T>> {
|
||||
if (ascendingTs.isEmpty()) {
|
||||
return listOf(this)
|
||||
}
|
||||
@@ -27,4 +46,16 @@ fun Segment.splitAt(ascendingTs: List<Double>, weldEpsilon: Double = 1E-6): List
|
||||
return ascendingTs.windowed(2, 1).map {
|
||||
sub(it[0], it[1])
|
||||
}
|
||||
}
|
||||
|
||||
fun Segment2D.splitAt(ascendingTs: List<Double>,
|
||||
weldEpsilon: Double = 1E-6) : List<Segment2D> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return splitAtBase(ascendingTs, weldEpsilon) as List<Segment2D>
|
||||
}
|
||||
|
||||
fun Segment3D.splitAt(ascendingTs: List<Double>,
|
||||
weldEpsilon: Double = 1E-6) : List<Segment3D> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return splitAtBase(ascendingTs, weldEpsilon) as List<Segment3D>
|
||||
}
|
||||
Reference in New Issue
Block a user