[orx-shapes] Handle RectifiedPath3D.path better

This commit is contained in:
Edwin Jakobs
2024-05-09 11:15:21 +02:00
parent 15cdba1881
commit 8f68c918f2
8 changed files with 44 additions and 45 deletions

View File

@@ -8,41 +8,41 @@ import kotlin.math.floor
class RectifiedContour(contour: ShapeContour, distanceTolerance: Double = 0.5, lengthScale: Double = 1.0) :
RectifiedPath<Vector2>(contour, distanceTolerance, lengthScale) {
fun velocity(t: Double): Vector2 {
return if (path.empty) {
return if (originalPath.empty) {
Vector2.ZERO
} else {
val (segment, st) = path.segment(rectify(safe(t)))
path.segments[segment].direction(st)
val (segment, st) = originalPath.segment(rectify(safe(t)))
originalPath.segments[segment].direction(st)
}
}
fun normal(t: Double): Vector2 {
return if (path.empty) {
return if (originalPath.empty) {
Vector2.UNIT_Y
} else {
(path as ShapeContour).normal(rectify(safe(t)))
(originalPath as ShapeContour).normal(rectify(safe(t)))
}
}
fun pose(t: Double): Matrix44 {
path as ShapeContour
return if (path.empty) {
originalPath as ShapeContour
return if (originalPath.empty) {
Matrix44.IDENTITY
} else {
path.pose(rectify(safe(t)))
originalPath.pose(rectify(safe(t)))
}
}
override fun sub(t0: Double, t1: Double): ShapeContour {
path as ShapeContour
if (path.empty) {
originalPath as ShapeContour
if (originalPath.empty) {
return ShapeContour.EMPTY
}
return if (path.closed) {
path.sub(rectify(t0.mod(1.0)) + floor(t0), rectify(t1.mod(1.0)) + floor(t1))
return if (originalPath.closed) {
originalPath.sub(rectify(t0.mod(1.0)) + floor(t0), rectify(t1.mod(1.0)) + floor(t1))
} else {
path.sub(rectify(t0), rectify(t1))
originalPath.sub(rectify(t0), rectify(t1))
}
}
@@ -51,5 +51,5 @@ class RectifiedContour(contour: ShapeContour, distanceTolerance: Double = 0.5, l
return super.splitAt(ascendingTs, weldEpsilon) as List<ShapeContour>
}
val contour: ShapeContour get() = path as ShapeContour
val contour: ShapeContour get() = originalPath as ShapeContour
}

View File

@@ -1,6 +1,5 @@
package org.openrndr.extra.shapes.rectify
import org.openrndr.extra.shapes.utilities.splitAt
import org.openrndr.extra.shapes.utilities.splitAtBase
import org.openrndr.math.EuclideanVector
import org.openrndr.math.clamp
@@ -11,12 +10,12 @@ import org.openrndr.shape.ShapeContour
* RectifiedContour provides an approximately uniform parameterization for [ShapeContour]
*/
abstract class RectifiedPath<T : EuclideanVector<T>>(
open val path: Path<T>,
val originalPath: Path<T>,
distanceTolerance: Double = 0.5,
lengthScale: Double = 1.0
) {
val points =
path.equidistantPositionsWithT((path.length * lengthScale).toInt().coerceAtLeast(2), distanceTolerance)
originalPath.equidistantPositionsWithT((originalPath.length * lengthScale).toInt().coerceAtLeast(2), distanceTolerance)
val intervals by lazy {
points.zipWithNext().map {
@@ -25,7 +24,7 @@ abstract class RectifiedPath<T : EuclideanVector<T>>(
}
internal fun safe(t: Double): Double {
return if (path.closed) {
return if (originalPath.closed) {
t.mod(1.0)
} else {
t.clamp(0.0, 1.0)
@@ -33,10 +32,10 @@ abstract class RectifiedPath<T : EuclideanVector<T>>(
}
/**
* computes a rectified t-value for [path]
* computes a rectified t-value for [originalPath]
*/
fun rectify(t: Double): Double {
if (path.empty) {
if (originalPath.empty) {
return 0.0
} else {
if (t <= 0.0) {
@@ -56,7 +55,7 @@ abstract class RectifiedPath<T : EuclideanVector<T>>(
}
fun inverseRectify(t: Double): Double {
if (path.empty) {
if (originalPath.empty) {
return 0.0
} else {
if (t <= 0.0) {
@@ -85,18 +84,18 @@ abstract class RectifiedPath<T : EuclideanVector<T>>(
}
fun position(t: Double): T {
return if (path.empty) {
path.infinity
return if (originalPath.empty) {
originalPath.infinity
} else {
path.position(rectify(safe(t)))
originalPath.position(rectify(safe(t)))
}
}
fun direction(t: Double): T {
return if (path.empty) {
path.infinity
return if (originalPath.empty) {
originalPath.infinity
} else {
path.direction(rectify(safe(t)))
originalPath.direction(rectify(safe(t)))
}
}
@@ -107,6 +106,6 @@ abstract class RectifiedPath<T : EuclideanVector<T>>(
* @since orx 0.4.4
*/
open fun splitAt(ascendingTs: List<Double>, weldEpsilon: Double = 1E-6): List<Path<T>> {
return path.splitAtBase(ascendingTs.map { rectify(it) }, weldEpsilon)
return originalPath.splitAtBase(ascendingTs.map { rectify(it) }, weldEpsilon)
}
}

View File

@@ -7,7 +7,7 @@ import kotlin.math.floor
class RectifiedPath3D(contour: Path3D, distanceTolerance: Double = 0.5, lengthScale: Double = 1.0) :
RectifiedPath<Vector3>(contour, distanceTolerance, lengthScale) {
override val path: Path3D = super.path as Path3D
val path: Path3D get() = originalPath as Path3D
override fun sub(t0: Double, t1: Double): Path3D {
if (path.empty) {