commonMain.adjust.ContourAdjusterEdge.kt Maven / Gradle / Ivy
The newest version!
package org.openrndr.extra.shapes.adjust
import org.openrndr.math.Vector2
import org.openrndr.shape.ShapeContour
import kotlin.jvm.JvmRecord
@JvmRecord
data class ContourAdjusterEdge(val contourAdjuster: ContourAdjuster, val segmentIndex: () -> Int) {
val startPosition
get() = contourAdjuster.contour.segments[segmentIndex()].start
val endPosition
get() = contourAdjuster.contour.segments[segmentIndex()].end
fun position(t: Double): Vector2 {
return contourAdjuster.contour.segments[segmentIndex()].position(t)
}
fun normal(t: Double): Vector2 {
return contourAdjuster.contour.segments[segmentIndex()].normal(t)
}
val length: Double
get() {
return contourAdjuster.contour.segments[segmentIndex()].length
}
/**
* A [ContourAdjusterVertex] interface for the start-vertex of the edge
*/
val start
get() = ContourAdjusterVertex(contourAdjuster, segmentIndex)
/**
* A [ContourAdjusterVertex] interface for the end-vertex of the edge
*/
val end
get() = ContourAdjusterVertex(
contourAdjuster,
{ (segmentIndex() + 1).mod(contourAdjuster.contour.segments.size) })
/**
* A link to the edge before this edge
*/
val previous: ContourAdjusterEdge?
get() = if (contourAdjuster.contour.closed) {
this.copy(segmentIndex = { (segmentIndex() - 1).mod(contourAdjuster.contour.segments.size) })
} else {
if (segmentIndex() > 0) {
this.copy(segmentIndex = { segmentIndex() - 1 })
} else {
null
}
}
/**
* A link to the edge after this edge
*/
val next: ContourAdjusterEdge?
get() = if (contourAdjuster.contour.closed) {
this.copy(segmentIndex = { (segmentIndex() + 1).mod(contourAdjuster.contour.segments.size) })
} else {
if (segmentIndex() < contourAdjuster.contour.segments.size - 1) {
this.copy(segmentIndex = { segmentIndex() + 1 })
} else {
null
}
}
fun select() {
contourAdjuster.selectEdge(segmentIndex())
}
internal fun wrap(block: ContourEdge.() -> ContourEdge) {
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(openContour: ShapeContour) = wrap { replacedWith(openContour) }
fun sub(t0: Double, t1: Double, updateTangents: Boolean = true) {
contourAdjuster.contour =
ContourEdge(contourAdjuster.contour, segmentIndex())
.subbed(t0, t1)
.contour
}
fun moveStartBy(translation: Vector2, updateTangents: Boolean = true) = wrap { startMovedBy(translation, updateTangents) }
fun moveControl0By(translation: Vector2) = wrap { control0MovedBy(translation) }
fun moveControl1By(translation: Vector2) = wrap { control1MovedBy(translation) }
fun moveEndBy(translation: Vector2, updateTangents: Boolean = true) = wrap { startMovedBy(translation, updateTangents) }
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy