Last active
December 17, 2015 22:19
-
-
Save GyrosOfWar/5680942 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package at.wambo.lsystem | |
import org.jsfml.graphics.VertexArray | |
/** | |
* User: Martin | |
* Date: 27.05.13 | |
* Time: 16:50 | |
*/ | |
class LSystem(private val axiom: String, | |
private val iterations: Int, | |
private val angle: Double, | |
private val distance: Int, | |
val xSize: Int, | |
val ySize: Int) | |
(val rules: PartialFunction[Char, String]) { | |
private var current: String = axiom | |
private val td: TurtleDrawing = new TurtleDrawing(xSize, ySize) | |
def step() { | |
for (x <- 1 until iterations) { | |
current = applyRules(current, rules) | |
} | |
} | |
def draw(): VertexArray = { | |
for (c <- current) { | |
c match { | |
case 'F' | 'G' => td.forward(distance) | |
case '+' => td.anglePlus(angle) | |
case '-' => td.angleMinus(angle) | |
case '[' => td.pushStack() | |
case ']' => td.popStack() | |
case 'X' | 'Y' => { } | |
case _ => throw new IllegalArgumentException("Not a valid character: " + c) | |
} | |
} | |
td.vertices | |
} | |
private def applyRules(state: String, rules: PartialFunction[Char, String]): String = | |
current.map { | |
c => if(rules.isDefinedAt(c)) rules(c) | |
else c | |
}.mkString | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package at.wambo.lsystem | |
import org.jsfml.graphics._ | |
import org.jsfml.window.{Keyboard, Mouse, VideoMode} | |
import org.jsfml.window.event.Event | |
import org.jsfml.system.{Vector2f, Vector2i} | |
/** | |
* User: Martin | |
* Date: 29.05.13 | |
* Time: 15:17 | |
*/ | |
object Main { | |
var mouseDrag: Boolean = false | |
var oldMousePos: Vector2i = new Vector2i(0, 0) | |
val xSize = 1280 | |
val ySize = 800 | |
def handleEvents(window: RenderWindow, event: Event, view: View) { | |
event.`type` match { | |
case Event.Type.CLOSED => window.close() | |
case Event.Type.MOUSE_BUTTON_PRESSED => mouseDrag = true | |
case Event.Type.MOUSE_BUTTON_RELEASED => mouseDrag = false | |
case Event.Type.MOUSE_MOVED if mouseDrag => { | |
val pos = Mouse.getPosition(window) | |
val delta = new Vector2f(oldMousePos.x - pos.x, oldMousePos.y - pos.y) | |
view.move(delta) | |
oldMousePos = pos | |
} | |
case Event.Type.KEY_PRESSED => { | |
event.asKeyEvent().key match { | |
case Keyboard.Key.W => view.move(0, -4) | |
case Keyboard.Key.S => view.move(0, 4) | |
case Keyboard.Key.A => view.move(-4, 0) | |
case Keyboard.Key.D => view.move(4, 0) | |
case _ => {} | |
} | |
} | |
case _ => {} | |
} | |
} | |
def main(args: Array[String]) { | |
val window = new RenderWindow(new VideoMode(xSize, ySize), "L-System") | |
val defaultView = window.getView | |
val view = new View(defaultView.getCenter, defaultView.getSize) | |
view.setCenter(xSize / 2.0f, ySize / 2.0f) | |
val koch = new LSystem("F", 5, Math.PI / 2.0, 10, 800, 600)({ | |
c: Char => c match { | |
case 'F' => "F+F-F-F+F" | |
} | |
}) | |
koch.step() | |
val vertices = koch.draw() | |
while (window.isOpen) { | |
val e = window.pollEvent() | |
if (e != null) { | |
handleEvents(window, e, view) | |
} | |
window.clear() | |
window.draw(vertices) | |
window.display() | |
window.setView(view) | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package at.wambo.lsystem | |
import org.jsfml.graphics._ | |
import org.jsfml.system.Vector2f | |
import java.util | |
/** | |
* User: Martin | |
* Date: 27.05.13 | |
* Time: 16:50 | |
*/ | |
class TurtleDrawing(xSize: Int, | |
ySize: Int) { | |
val vertices: VertexArray = new VertexArray(PrimitiveType.LINES) | |
var color: Color = Color.WHITE | |
private val stack: util.Stack[Double] = new util.Stack[Double] | |
private var position: Vector2f = new Vector2f(0, 0) | |
private var angle: Double = 0 | |
/** | |
* Moves the turtle forward. | |
* @param distance distance in pixels to move forward | |
*/ | |
def forward(distance: Float) { | |
vertices.add(new Vertex(position, color)) | |
val newPos = new Vector2f((position.x + Math.cos(angle) * distance).asInstanceOf[Float], | |
(position.y + Math.sin(angle) * distance).asInstanceOf[Float]) | |
position = newPos | |
vertices.add(new Vertex(newPos, color)) | |
} | |
/** | |
* Increases the angle by a given amount. | |
* @param d Amount to increase the angle with, in radians. | |
*/ | |
def anglePlus(d: Double) { | |
angle += d | |
} | |
/** | |
* Decreases the angle by a given amount. | |
* @param d Amount to decrease the angle with, in radians. | |
*/ | |
def angleMinus(d: Double) { | |
angle -= d | |
} | |
/** | |
* Moves the turtle to a given direction, | |
* without drawing anything. | |
* @param x X coordinate for new position | |
* @param y Y coordinate for new position | |
*/ | |
def moveTo(x: Float, y: Float) { | |
position = new Vector2f(x, y) | |
} | |
/** | |
* Pushes the current position and angle to the stack | |
*/ | |
def pushStack() { | |
stack push position.x | |
stack push position.y | |
stack push angle | |
} | |
/** | |
* Gets the position and angle from the stack and | |
* restores it. | |
*/ | |
def popStack() { | |
val y = stack.pop.asInstanceOf[Float] | |
val x = stack.pop.asInstanceOf[Float] | |
val ang = stack.pop | |
moveTo(x, y) | |
angle = ang | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment