diff --git a/orx-shapes/src/commonMain/kotlin/adjust/ContourAdjuster.kt b/orx-shapes/src/commonMain/kotlin/adjust/ContourAdjuster.kt index 2ff88d01..773f0391 100644 --- a/orx-shapes/src/commonMain/kotlin/adjust/ContourAdjuster.kt +++ b/orx-shapes/src/commonMain/kotlin/adjust/ContourAdjuster.kt @@ -32,7 +32,7 @@ class ContourAdjuster(var contour: ShapeContour) { /** * selected vertex indices */ - var vertexSelection = List(contour.segments.size + if (contour.closed) 1 else 0) { it } + var vertexSelection = List(contour.segments.size + if (contour.closed) 0 else 1) { it } /** * selected edge indices diff --git a/orx-shapes/src/commonMain/kotlin/adjust/ContourEdge.kt b/orx-shapes/src/commonMain/kotlin/adjust/ContourEdge.kt index cfa4e397..73915f8c 100644 --- a/orx-shapes/src/commonMain/kotlin/adjust/ContourEdge.kt +++ b/orx-shapes/src/commonMain/kotlin/adjust/ContourEdge.kt @@ -233,8 +233,10 @@ data class ContourEdge( } else { refIn.cubic.control } - control[1] = control[1].transformedBy(transform) - newSegments[segmentInIndex] = refIn.copy(end = segment.start.transformedBy(transform), control = control) + if (control.isNotEmpty()) { + control[1] = control[1].transformedBy(transform) + } + newSegments[segmentInIndex] = refIn.copy(end = segment.start.transformedBy(transform)) } if (refOut != null) { val control = if (refOut.linear || !updateTangents) { @@ -242,7 +244,9 @@ data class ContourEdge( } else { refOut.cubic.control } - control[0] = control[0].transformedBy(transform) + if (control.isNotEmpty()) { + control[0] = control[0].transformedBy(transform) + } newSegments[segmentOutIndex] = refOut.copy(start = segment.end.transformedBy(transform)) } diff --git a/orx-shapes/src/jvmTest/kotlin/TestAdjustContour.kt b/orx-shapes/src/jvmTest/kotlin/TestAdjustContour.kt new file mode 100644 index 00000000..8ac90e0e --- /dev/null +++ b/orx-shapes/src/jvmTest/kotlin/TestAdjustContour.kt @@ -0,0 +1,96 @@ +import org.openrndr.extra.shapes.adjust.adjustContour +import org.openrndr.math.Vector2 +import org.openrndr.shape.LineSegment +import org.openrndr.shape.Rectangle +import kotlin.math.cos +import kotlin.math.sin +import kotlin.test.Test +import kotlin.test.assertEquals + + +class TestAdjustContour { + @Test + fun testSingleLinearSegment() { + val adjusted = adjustContour(LineSegment(0.0, 0.0, 100.0, 100.0).contour) { + selectVertex(0) + vertex.moveTo(Vector2(50.0, 50.0)) + + selectVertex(1) + vertex.moveTo(Vector2(150.0, 150.0)) + } + assertEquals(1, adjusted.segments.size) + assertEquals(50.0, adjusted.segments[0].start.x, 1E-6) + assertEquals(50.0, adjusted.segments[0].start.y, 1E-6) + assertEquals(150.0, adjusted.segments[0].end.x, 1E-6) + assertEquals(150.0, adjusted.segments[0].end.y, 1E-6) + } + + @Test + fun testSingleLinearSegmentDefaultVertexSelection() { + val adjusted = adjustContour(LineSegment(0.0, 0.0, 100.0, 100.0).contour) { + for (v in vertices) { + v.moveBy(Vector2(50.0, 50.0)) + } + } + assertEquals(1, adjusted.segments.size) + assertEquals(50.0, adjusted.segments[0].start.x, 1E-6) + assertEquals(50.0, adjusted.segments[0].start.y, 1E-6) + assertEquals(150.0, adjusted.segments[0].end.x, 1E-6) + assertEquals(150.0, adjusted.segments[0].end.y, 1E-6) + } + + @Test + fun testSingleLinearSegmentDefaultEdgeSelection() { + val adjusted = adjustContour(LineSegment(0.0, 0.0, 100.0, 100.0).contour) { + for (e in edges) { + e.moveBy(Vector2(50.0, 50.0)) + } + } + assertEquals(1, adjusted.segments.size) + assertEquals(50.0, adjusted.segments[0].start.x, 1E-6) + assertEquals(50.0, adjusted.segments[0].start.y, 1E-6) + assertEquals(150.0, adjusted.segments[0].end.x, 1E-6) + assertEquals(150.0, adjusted.segments[0].end.y, 1E-6) + } + + + @Test + fun testSingleQuadraticSegment() { + val adjusted = adjustContour(LineSegment(0.0, 0.0, 100.0, 100.0).segment.quadratic.contour) { + selectVertex(0) + vertex.moveTo(Vector2(50.0, 50.0)) + + selectVertex(1) + vertex.moveTo(Vector2(150.0, 150.0)) + } + assertEquals(1, adjusted.segments.size) + assertEquals(50.0, adjusted.segments[0].start.x, 1E-6) + assertEquals(50.0, adjusted.segments[0].start.y, 1E-6) + assertEquals(150.0, adjusted.segments[0].end.x, 1E-6) + assertEquals(150.0, adjusted.segments[0].end.y, 1E-6) + } + + @Test + fun testEdgeTransform() { + val adjusted = adjustContour(LineSegment(0.0, 0.0, 100.0, 100.0).segment.quadratic.contour) { + for (e in edges) { + e.moveBy(Vector2(50.0, 50.0)) + } + } + } + + @Test + fun testRectangleEdgeTransform() { + var r = Rectangle(0.0, 0.0, 400.0, 400.0).contour + val seconds = 0.0 + r = adjustContour(r) { + selectEdge(1) + for (edge in edges) { + edge.moveBy(Vector2(sin(seconds) * 10.0, cos(seconds) * 5.0)) + } + } + + + } + +} \ No newline at end of file