Tiny L-System Only one.

by smirnov48 forked from Tiny L-System (diff: 56)
Tiny LSystem Demo
one fractal - many iterations
♥0 | Line 176 | Modified 2013-09-03 01:39:26 | MIT License
play

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;

    }
}