Tiny L-System Only one.
forked from Tiny L-System (diff: 56)
Tiny LSystem Demo one fractal - many iterations
ActionScript3 source code
/**
* Copyright smirnov48 ( http://wonderfl.net/user/smirnov48 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/7oad
*/
// forked from smirnov48's Tiny L-System
/**
* Tiny LSystem Demo
* one fractal - many iterations
*
* F - forward with drawing
* b - forward without drawing
* + - increase angle
* - - decrease angle
* [ - save state in stack
* ] - return to previous state
*/
package {
import flash.display.Sprite;
import flash.events.TimerEvent;
import flash.utils.Timer;
public class TinyLSystemDemo extends Sprite {
private var view:int = 0;
private var tinyLSystem:TinyLSystem;
public function TinyLSystemDemo() {
tinyLSystem = new TinyLSystem();
addChild(tinyLSystem);
tinyLSystem.x = stage.stageWidth/2;
tinyLSystem.y = stage.stageHeight/2;
var timer:Timer = new Timer(1000);
timer.addEventListener(TimerEvent.TIMER, onTimer);
timer.start();
onTimer(null);
}
private function setupLSytem():void {
tinyLSystem.setAngle(36 * Math.PI/180);
tinyLSystem.setAxiom("[X]++[X]++[X]++[X]++[X]");
tinyLSystem.setRule("Y", "ZF++WF----XF[-ZF----YF]++");
tinyLSystem.setRule("X", "+ZF--WF[---YF--XF]+");
tinyLSystem.setRule("Z", "-YF++XF[+++ZF++WF]-");
tinyLSystem.setRule("W", "--ZF++++YF[+WF++++XF]--XF");
tinyLSystem.setRule("F", "F+F-");
}
private function onTimer(event:TimerEvent):void {
switch (view++) {
case 0:
setupLSytem();
tinyLSystem.setIterations(2);
tinyLSystem.setLength(8);
break;
case 1:
setupLSytem();
tinyLSystem.setIterations(3);
tinyLSystem.setLength(4);
break;
case 2:
setupLSytem();
tinyLSystem.setIterations(4);
tinyLSystem.setLength(3);
break;
case 3:
setupLSytem();
tinyLSystem.setIterations(5);
tinyLSystem.setLength(2);
break;
case 4:
setupLSytem();
tinyLSystem.setIterations(6);
tinyLSystem.setLength(1);
view = 0;
break;
}
tinyLSystem.draw();
}
}
}
import flash.display.Sprite;
internal class TinyLSystem extends Sprite {
private var length:Number = 2;
private var angle:Number = Math.PI/2;
private var iterations:int = 5;
private var axiom:String = 'F';
private var rules:Array = new Array();
private var sequence:String;
public function setLength(len:Number):void {
length = len;
}
public function setAngle(a:Number):void {
angle = a;
}
public function setAxiom(str:String):void {
axiom = str;
}
public function setRule(token:String, replacement:String):void {
rules.push({token:token, replacement:replacement});
}
public function setIterations(i:int):void {
iterations = i;
}
public function draw():void {
graphics.clear();
computeResultSequence();
var turtle:Turtle = new Turtle(this);
turtle.setStepLength(length);
turtle.setRotationAngle(angle);
for (var i:int = 0; i < sequence.length; i++) {
var command:String = sequence.charAt(i);
turtle.processCommand(command);
}
}
private function computeResultSequence():void {
sequence = axiom;
for (var i:int = 0; i < iterations; i++) {
var temp:String = '';
for (var k:int = 0; k < sequence.length; k++) {
var token:String = sequence.charAt(k);
var wasInRules = false;
for (var j:int = 0; j < rules.length; j++) {
if (rules[j].token == token) {
temp += rules[j].replacement;
wasInRules = true;
break;
}
}
if (!wasInRules) {
temp += token;
}
}
sequence = temp;
}
}
}
internal class Turtle {
public var stack:Array = new Array();
private var length:Number = 2;
private var angle:Number = Math.PI/2;
private var canvas:Sprite;
private var curAngle:Number = 0;
private var x:Number = 0;
private var y:Number = 0;
public function Turtle (canvas:Sprite) {
this.canvas = canvas;
canvas.graphics.lineStyle(0,0x000000);
canvas.graphics.moveTo(x,y);
}
public function setStepLength(length:Number):void {
this.length = length;
}
public function setRotationAngle(angle:Number):void {
this.angle = angle;
}
public function processCommand(command:String):void {
switch (command) {
case 'F':
x += Math.cos(curAngle) * length;
y += Math.sin(curAngle) * length;
canvas.graphics.lineTo(x,y);
break;
case 'b':
x += Math.cos(curAngle) * length;
y += Math.sin(curAngle) * length;
canvas.graphics.moveTo(x,y);
break;
case '+':
curAngle += angle;
break;
case '-':
curAngle -= angle;
break;
case '[':
stack.push(new State(x,y,curAngle));
break;
case ']':
var prev:State = stack.pop() as State;
x = prev.x;
y = prev.y;
canvas.graphics.moveTo(x,y);
curAngle = prev.angle;
break;
default :
/* Nothing */
}
}
}
internal class State {
public var x:Number;
public var y:Number;
public var angle:Number;
public function State(x:Number, y:Number, angle:Number){
this.x = x;
this.y = y;
this.angle = angle;
}
}
