Update for OPENRNDR segment and path generalizations

This commit is contained in:
Edwin Jakobs
2024-03-19 16:31:45 +01:00
parent 8fe7631570
commit af6d35c59b
37 changed files with 579 additions and 277 deletions

View 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()
}
}
}

View File

@@ -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>
}