diff --git a/settings.gradle b/settings.gradle index 52bd101..d360a94 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,2 @@ -rootProject.name = 'openrndr-template' +rootProject.name = 'openrndr-hpgl' diff --git a/src/main/kotlin/com/martianwabbit/hpglWriter.kt b/src/main/kotlin/com/martianwabbit/hpglWriter.kt index a06b40c..c91496e 100644 --- a/src/main/kotlin/com/martianwabbit/hpglWriter.kt +++ b/src/main/kotlin/com/martianwabbit/hpglWriter.kt @@ -16,64 +16,64 @@ class HPGL( private val height: Int = 0 ) { fun generateFromComposition(composition: Composition): String { - val result = StringBuilder() + val hpgl = StringBuilder() - result.appendln("IN;") // Initialize the plotter + hpgl.cmd("IN") - // Setup coordinates + // Setup plotter coordinates if (p1 != Vector2.ZERO || p2 != Vector2.ZERO) { - result.appendln("IP${p1.getCoords()},${p2.getCoords()};") + hpgl.cmd("IP", p1, p2) } // Setup scaling + // If no width and height is provided it'll default to the plotter's scaling. + // Ideally this should always be the screen width and height as that'll make it + // so that everything scales correctly from the screensize into the page size. if (width == 0 && height == 0) { - result.appendln("SC;") + hpgl.cmd("SC") } else { - result.appendln("SC0,$width,0,$height;") + hpgl.cmd("SC", Vector2(.0, width.toDouble()), Vector2(.0, height.toDouble())) } - result.appendln("PA0,0;") // Plot absolutely + hpgl.cmd("PU") // Raise Pen + hpgl.cmd("PA", Vector2.ZERO) // Plot absolutely composition.root.traverse { stage -> if (stage == Stage.Before) { when (this) { is ShapeNode -> { - for (shape in this.shape.contours) { + this.shape.contours.forEach { shape -> val segments = shape.sampleLinear().segments segments.forEachIndexed { i, segment -> if (i == 0) { - result.appendln("PU${segment.start.getCoords()};") // Go to shape start - result.appendln("PD${segment.end.getCoords()};") + hpgl.cmd("PU", segment.start) // Go to shape start + hpgl.cmd("PD", segment.end) } else { - result.appendln("PD${segment.start.getCoords()};") // PD coordinates for all other segments - result.appendln("PD${segment.end.getCoords()};") // PD coordinates for all other segments + hpgl.cmd("PD", segment.start) // PD coordinates for all other segments + hpgl.cmd("PD", segment.end) // PD coordinates for all other segments } } - result.appendln("PU;") // Done plotting + hpgl.cmd("PU") // Done plotting } } is SelectPen -> { - result.appendln("SP${this.penNumber};") + hpgl.cmd("SP", this.penNumber) } is VelocitySelect -> { - result.appendln("VS${this.velocity};") + hpgl.cmd("VS", this.velocity) } } } } - result.appendln("PA0,0;") - return result.toString() + hpgl.cmd("PA", Vector2.ZERO) + return hpgl.toString() } } -private fun Vector2.getCoords(): String { - return "$x,$y" -} - private enum class Stage { Before, After @@ -104,3 +104,14 @@ fun CompositionDrawer.velocitySelect(velocity: Double) { this.root.children.add(VelocitySelect(velocity)) } +private fun StringBuilder.cmd(cmd: String) = this.appendln("$cmd;") +private fun StringBuilder.cmd(cmd: String, i: Int) = this.appendln("$cmd${i};") +private fun StringBuilder.cmd(cmd: String, i: Double) = this.appendln("$cmd${i};") +private fun StringBuilder.cmd(cmd: String, vararg vectors: Vector2) { + this.appendln(vectors.joinToString(prefix = cmd, postfix = ";") { it.coords }) +} + +private val Vector2.coords: String + get() { + return "$x,$y" + }