From 2293d5d74ec1020cf47f666a95747d02d860c70c Mon Sep 17 00:00:00 2001 From: Edwin Jakobs Date: Sat, 28 Oct 2023 14:01:39 +0200 Subject: [PATCH] [orx-shapes] Add splitIn --- .../kotlin/adjust/ContourAdjusterEdge.kt | 27 ++++++++++++------- .../commonMain/kotlin/adjust/ContourEdge.kt | 22 ++++++++++++--- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/orx-shapes/src/commonMain/kotlin/adjust/ContourAdjusterEdge.kt b/orx-shapes/src/commonMain/kotlin/adjust/ContourAdjusterEdge.kt index a588653f..4a57f2a1 100644 --- a/orx-shapes/src/commonMain/kotlin/adjust/ContourAdjusterEdge.kt +++ b/orx-shapes/src/commonMain/kotlin/adjust/ContourAdjusterEdge.kt @@ -11,17 +11,15 @@ data class ContourAdjusterEdge(val contourAdjuster: ContourAdjuster, val segment val endPosition get() = contourAdjuster.contour.segments[segmentIndex()].end - fun position(t: Double) : Vector2 { + fun position(t: Double): Vector2 { return contourAdjuster.contour.segments[segmentIndex()].position(t) } - fun normal(t: Double) : Vector2 { + fun normal(t: Double): Vector2 { return contourAdjuster.contour.segments[segmentIndex()].normal(t) } - - /** * A [ContourAdjusterVertex] interface for the start-vertex of the edge */ @@ -32,7 +30,9 @@ data class ContourAdjusterEdge(val contourAdjuster: ContourAdjuster, val segment * A [ContourAdjusterVertex] interface for the end-vertex of the edge */ val end - get() = ContourAdjusterVertex(contourAdjuster, { (segmentIndex() + 1).mod(contourAdjuster.contour.segments.size) } ) + get() = ContourAdjusterVertex( + contourAdjuster, + { (segmentIndex() + 1).mod(contourAdjuster.contour.segments.size) }) /** * A link to the edge before this edge @@ -56,7 +56,7 @@ data class ContourAdjusterEdge(val contourAdjuster: ContourAdjuster, val segment this.copy(segmentIndex = { (segmentIndex() + 1).mod(contourAdjuster.contour.segments.size) }) } else { if (segmentIndex() < contourAdjuster.contour.segments.size - 1) { - this.copy(segmentIndex = { segmentIndex() + 1 } ) + this.copy(segmentIndex = { segmentIndex() + 1 }) } else { null } @@ -65,27 +65,36 @@ data class ContourAdjusterEdge(val contourAdjuster: ContourAdjuster, val segment fun select() { contourAdjuster.selectEdge(segmentIndex()) } + private fun wrap(block: ContourEdge.() -> ContourEdge) { - val newEdge = ContourEdge(contourAdjuster.contour, segmentIndex()).block() + val newEdge = ContourEdge(contourAdjuster.contour, segmentIndex()).block() contourAdjuster.contour = newEdge.contour contourAdjuster.updateSelection(newEdge.adjustments) } + fun toLinear() = wrap { toLinear() } fun toCubic() = wrap { toCubic() } fun splitAt(t: Double) = wrap { splitAt(t) } + + /** + * split edge in [numberOfParts] parts of equal length + */ + fun splitIn(numberOfParts: Int) = wrap { splitIn(numberOfParts) } + fun moveBy(translation: Vector2, updateTangents: Boolean = true) = wrap { movedBy(translation, updateTangents) } fun rotate(rotationInDegrees: Double, anchorT: Double = 0.5, updateTangents: Boolean = true) = wrap { rotatedBy(rotationInDegrees, anchorT, updateTangents) } + fun scale(scaleFactor: Double, anchorT: Double = 0.5, updateTangents: Boolean = true) = wrap { scaledBy(scaleFactor, anchorT, updateTangents = true) } - fun replaceWith(t:Double, updateTangents: Boolean = true) = wrap { replacedWith(t, updateTangents) } + fun replaceWith(t: Double, updateTangents: Boolean = true) = wrap { replacedWith(t, updateTangents) } fun replaceWith(openContour: ShapeContour) = wrap { replacedWith(openContour) } - fun sub(t0:Double, t1: Double, updateTangents: Boolean = true) { + fun sub(t0: Double, t1: Double, updateTangents: Boolean = true) { contourAdjuster.contour = ContourEdge(contourAdjuster.contour, segmentIndex()) .subbed(t0, t1) diff --git a/orx-shapes/src/commonMain/kotlin/adjust/ContourEdge.kt b/orx-shapes/src/commonMain/kotlin/adjust/ContourEdge.kt index 3d4ec46b..c2db5cb6 100644 --- a/orx-shapes/src/commonMain/kotlin/adjust/ContourEdge.kt +++ b/orx-shapes/src/commonMain/kotlin/adjust/ContourEdge.kt @@ -1,5 +1,7 @@ package org.openrndr.extra.shapes.adjust +import org.openrndr.extra.shapes.rectify.rectified +import org.openrndr.extra.shapes.utilities.fromContours import org.openrndr.extra.shapes.utilities.insertPointAt import org.openrndr.math.Matrix44 import org.openrndr.math.Vector2 @@ -111,11 +113,25 @@ data class ContourEdge( return ContourEdge(ShapeContour.fromSegments(newSegments, contour.closed), segmentIndex, adjustments) } - fun replacedWith(openContour: ShapeContour) : ContourEdge { + fun splitIn(parts: Int): ContourEdge { + if (contour.empty || parts < 2) { + return withoutAdjustments() + } + val segment = contour.segments[segmentIndex] + val r = segment.contour.rectified() + val newSegments = (0..parts).map { + it.toDouble() / parts + }.windowed(2, 1).map { + r.sub(it[0], it[1]) + } + return replacedWith(ShapeContour.fromContours(newSegments, false)) + } + + fun replacedWith(openContour: ShapeContour): ContourEdge { if (contour.empty) { return withoutAdjustments() } - require(!openContour.closed) { "openContour should be open"} + require(!openContour.closed) { "openContour should be open" } val segment = contour.segments[segmentIndex] var newSegments = contour.segments.toMutableList() @@ -255,7 +271,5 @@ data class ContourEdge( translate(-anchor) }, updateTangents) } - - }