[orx-shapes] Add inverseRectify to RectifiedContour
This commit is contained in:
@@ -10,8 +10,15 @@ import kotlin.math.floor
|
||||
/**
|
||||
* RectifiedContour provides an approximately uniform parameterization for [ShapeContour]
|
||||
*/
|
||||
class RectifiedContour(val contour: ShapeContour, distanceTolerance: Double = 0.5, lengthScale: Double = 1.0, ) {
|
||||
val points = contour.equidistantPositionsWithT((contour.length * lengthScale).toInt().coerceAtLeast(2), distanceTolerance)
|
||||
class RectifiedContour(val contour: ShapeContour, distanceTolerance: Double = 0.5, lengthScale: Double = 1.0) {
|
||||
val points =
|
||||
contour.equidistantPositionsWithT((contour.length * lengthScale).toInt().coerceAtLeast(2), distanceTolerance)
|
||||
|
||||
val intervals by lazy {
|
||||
points.zipWithNext().map {
|
||||
Pair(it.first.second, it.second.second)
|
||||
}
|
||||
}
|
||||
|
||||
private fun safe(t: Double): Double {
|
||||
return if (contour.closed) {
|
||||
@@ -44,6 +51,35 @@ class RectifiedContour(val contour: ShapeContour, distanceTolerance: Double = 0.
|
||||
}
|
||||
}
|
||||
|
||||
fun inverseRectify(t: Double): Double {
|
||||
if (contour.empty) {
|
||||
return 0.0
|
||||
} else {
|
||||
if (t <= 0.0) {
|
||||
return 0.0
|
||||
} else if (t >= 1.0) {
|
||||
return 1.0
|
||||
} else {
|
||||
val index = intervals.binarySearch {
|
||||
if (t < it.first) {
|
||||
1
|
||||
} else if (t > it.second) {
|
||||
-1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
val t0 = t - intervals[index].first
|
||||
val dt = intervals[index].second - intervals[index].first
|
||||
val f = t0 / dt
|
||||
val f0 = index.toDouble() / intervals.size
|
||||
val f1 = (index + 1.0) / intervals.size
|
||||
|
||||
return f0 * (1.0 - f) + f1 * f
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun position(t: Double): Vector2 {
|
||||
return if (contour.empty) {
|
||||
Vector2.INFINITY
|
||||
|
||||
20
orx-shapes/src/commonTest/kotlin/TestRectifiedContour.kt
Normal file
20
orx-shapes/src/commonTest/kotlin/TestRectifiedContour.kt
Normal file
@@ -0,0 +1,20 @@
|
||||
import org.openrndr.extra.shapes.rectify.rectified
|
||||
import org.openrndr.shape.Circle
|
||||
import org.openrndr.shape.Ellipse
|
||||
import kotlin.math.abs
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class TestRectifiedContour {
|
||||
|
||||
@Test
|
||||
fun testInverse() {
|
||||
val c = Ellipse(40.0, 40.0, 40.0, 80.0).contour.sub(0.0, 0.333)
|
||||
val r = c.rectified()
|
||||
val rt = r.rectify(0.125)
|
||||
val ri = r.inverseRectify(rt)
|
||||
|
||||
assertTrue(abs(ri-0.125) < 1E-5)
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user