Trying to figure sample out.

This commit is contained in:
David Diaz 2019-10-09 23:44:58 -06:00
parent a03cf20ad3
commit fb7613114b
2 changed files with 83 additions and 19 deletions

View File

@ -1,9 +1,13 @@
import com.martianwabbit.HPGL
import com.martianwabbit.logger
import org.openrndr.application import org.openrndr.application
import org.openrndr.color.ColorRGBa import org.openrndr.color.ColorRGBa
import org.openrndr.math.Vector2 import org.openrndr.math.Vector2
import org.openrndr.shape.CompositionDrawer import org.openrndr.shape.CompositionDrawer
import java.io.File import java.io.File
import com.martianwabbit.saveToHPGL import com.martianwabbit.saveToHPGL
import org.openrndr.Configuration
import org.openrndr.Program
fun main() = application { fun main() = application {
configure { configure {
@ -17,7 +21,9 @@ fun main() = application {
c.circle(Vector2(20.0, 20.0), 12.0) c.circle(Vector2(20.0, 20.0), 12.0)
c.composition.saveToHPGL(File("output.plt")) c.composition.saveToHPGL(File("output.plt"))
// this.application.exit()
this.application.exit()
drawer.background(ColorRGBa.WHITE) drawer.background(ColorRGBa.WHITE)
drawer.composition(c.composition) drawer.composition(c.composition)
} }

View File

@ -1,16 +1,44 @@
package com.martianwabbit package com.martianwabbit
import org.openrndr.shape.Composition import org.openrndr.math.Vector2
import org.openrndr.shape.CompositionNode import org.openrndr.shape.*
import org.openrndr.shape.GroupNode
import org.openrndr.shape.ShapeNode
import java.io.File import java.io.File
import java.util.logging.Logger import java.util.logging.Logger
import kotlin.math.pow
import kotlin.math.sqrt
val logger = Logger.getLogger("") val logger = Logger.getLogger("")
public fun Composition.saveToHPGL(file: File) { fun Composition.saveToHPGL(file: File) {
generateHPGL(this) HPGL().generateFromComposition(this)
}
class HPGL(pageSize: PageSize = PageSize.A4) {
fun generateFromComposition(composition: Composition) {
composition.root.traverse { shape ->
if (shape == Stage.Before) {
if (this is ShapeNode) {
this.shape.contours.forEach { shape ->
val i = shape.sampleEquidistant(200)
val rr = StringBuilder()
for (v in i.segments) {
rr.appendln("${v.start.x}, ${v.start.y}")
}
calculateSpline(shape.segments)
}
}
}
}
}
}
private fun Vector2.distanceTo(point: Vector2): Double {
return sqrt((point.x - this.x).pow(2.0) + (point.y - this.y).pow(2.0))
}
enum class PageSize {
A4,
A3
} }
private enum class Stage { private enum class Stage {
@ -18,20 +46,6 @@ private enum class Stage {
After After
} }
private fun generateHPGL(composition: Composition) {
composition.root.traverse { shape ->
if (shape == Stage.Before) {
if (this is ShapeNode) {
this.shape.contours.forEach { shape ->
shape.segments.forEach { segment ->
// Render these segments
}
}
}
}
}
}
private fun CompositionNode.traverse(cb: CompositionNode.(stage: Stage) -> Unit) { private fun CompositionNode.traverse(cb: CompositionNode.(stage: Stage) -> Unit) {
this.cb(Stage.Before) this.cb(Stage.Before)
@ -39,3 +53,47 @@ private fun CompositionNode.traverse(cb: CompositionNode.(stage: Stage) -> Unit)
this.children.forEach { it.traverse(cb) } this.children.forEach { it.traverse(cb) }
} }
} }
// These default values correspond to a centripetal Catmull-Rom spline
private fun calculateSpline(segments: List<Segment>, resolution: Int = 100, alpha: Double = .5, tension: Double = .0) {
val result = mutableListOf<Vector2>()
segments.forEach {
val points = mutableListOf<Vector2>()
points.add(it.start)
points.addAll(it.control)
points.add(it.end)
when(points.size) {
4 -> { // Catmull-Rom
val t0 = 0.0
val t1 = t0 + points[0].distanceTo(points[1]).pow(alpha)
val t2 = t1 + points[1].distanceTo(points[2]).pow(alpha)
val t3 = t2 + points[2].distanceTo(points[3]).pow(alpha)
val p0 = points[0]
val p1 = points[1]
val p2 = points[2]
val p3 = points[3]
val m1 = ((p1 - p0) / (t1 - t0) - (p2 - p0) / (t2 - t0) + (p2 - p1) / (t2 - t1)) * (1.0 - tension) * (t2 - t1)
val m2 = ((p2 - p1) / (t2 - t1) - (p3 - p1) / (t3 - t1) + (p3 - p2) / (t3 - t2)) * (1.0 - tension) * (t2 - t1)
val a = (p1 - p2) + m1 + m2 * 2.0
val b = ((p1 - p2) * -3.0) - m1 - m1 - m2
for (i in 0..100 step 10) {
val t = (i / 100).toDouble()
val r = a * t.pow(3) + b * t.pow(2) + m1 * t.pow(1) + p1
result.add(r)
}
}
}
}
val rr = StringBuilder()
for (v in result) {
rr.appendln("${v.x}, ${v.y}")
}
val a = Vector2(0.0, 10.0).distanceTo(Vector2(13.0, 12.0))
logger.info("done")
}