JavaScript code for producing Lindenmayer systems

From JSXGraph Wiki
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Here is an explanation of the JavaScript code that produces the pictures in L-systems. It uses the Turtle Graphics implementation of JSXGraph.

For example, the Sierpinski curve in L-systems is defined by the following Lindenmayer system:

var level = 6;
var axiom = 'A';
var rules = {
    'A':'B-A-B',
    'B':'A+B+A',
    '+' : '+',
    '-' : '-'
};
var symbols = { 'A':'F', 
                'B':'F', 
                '+':'+', 
                '-':'-', 
                '[':'[', 
                ']':']'  
              }; 
var angle = 60; 
var len = 500/Math.pow(2,level); 
t.setPos(-250*Math.pow(-1,level),-250); 
t.rt(90*Math.pow(-1,level));

JSXGraph for the various boards and the turtle graphics are initialized by the following code:

var t;
var turtle = [];
var brd = [];
brd[0] = JXG.JSXGraph.initBoard('box0', {boundingbox: [-300, 300, 300, -300]});
turtle[0] = brd[0].create('turtle');
var shrink = 1.0;

Here is the recursive code to expand an axiom of a Lindenmayer system into a string:

function expander(level,axiom,rules) {
    this.axiom = axiom;
    this.rules = rules;
    this.source = (level>1) ? new expander(level-1,axiom,rules) : (new function() {
        // Axiom:
        this.code = axiom;
        this.pos = 0;
        this.next = function() {
            if (this.pos>=this.code.length) return null;
            return this.code.charAt(this.pos++);
        }
    });
    
    this.code = '';
    this.pos = 0;
    this.next = function() {
        while (this.pos>=this.code.length) { // produce new symbols from source
            this.pos = 0;
            var pattern = this.source.next();
            if (!pattern) return null // Finished
            this.code = this.rules[pattern];
        }
        return this.code.charAt(this.pos++);
    }
}

The string of an Lindenmayer system can be plotted by the JSXGraph-powered turtle:

function plotter(generator,symbols,len,angle,t,shrink) {
    for (var c; c=generator.next(); c) {
        switch(symbols[c]) {
            case 'F':
                t.fd(len);
                break;
            case 'f':
                t.penUp();
                t.fd(len);
                t.penDown();
                break;
            case '+':
                t.lt(angle);
                break;
            case '-':
                t.rt(angle);
                break;
            case '[':
                t.pushTurtle();
                len *= shrink;
                break;
            case ']':
                t.popTurtle();
                len /= shrink;
                break;
            default:
                ;
        }
    }
    return null;
  }

After clicking on a run-button in L-systems the following code is started:

function run(nr) {
  brd[nr].suspendUpdate();
  var code = $('inputtext'+nr).value;
  if (code=='') { return; }
  t = turtle[nr];
  t.cs();
  t.hideTurtle();
  eval(code);
  var generator = new expander(level,axiom,rules);
  plotter(generator,symbols,len,angle,t,shrink);
  brd[nr].unsuspendUpdate();
}

function clearturtle(nr) {
  turtle[nr].cs();
}

References

The code for expander and plotter is an adaption of the code from http://www.intertwingly.net/blog/2006/07/06/Penrose-Tiling from Sam Ruby.