algorithmloopsprocessingl-systems

How to create a simple l-system in Processing


I want to create a simple l-system in Processing. I want to change every letter 'A' to 'AB' and every letter 'B' to 'A', starting with 'A'.

The result should look something like this:

A →
AB →
ABA →
ABAAB →
ABAABABA → etc...

(P.S. I don't know much about processing)


Solution

  • I suggest having a look in Processing > Examples > Topics > Franctals and L-Systems and at Daniel Shiffman's brilliant Nature of Code book, especially Chapter 8: Fractals (8.6 L-Systems)

    Nature of Code Chapter 8 image L-System generation sequence

    Nature of Code Chapter 8 image L-System notation sequence

    Nature of Code Chapter 8 image L-System generated tree image

    Also, be sure to check out Daniel Jones' L-System project: in includes explanations and Processing source code.

    Daniel Jones L-System poster

    Bellow is the PenroseTile example from Processing ported to Javascript and running on the P5.js port.

    var ds;
    function setup() {
      createCanvas(640, 360);
      ds = new PenroseLSystem();
      ds.simulate(4);
    }
    
    function draw() {
      background(0);
      ds.render();
    }
    
    //*
    function PenroseLSystem(){
    
      this.steps = 0;
      this.ruleW = "YF++ZF4-XF[-YF4-WF]++";
      this.ruleX = "+YF--ZF[3-WF--XF]+";
      this.ruleY = "-WF++XF[+++YF++ZF]-";
      this.ruleZ = "--YF++++WF[+ZF++++XF]--XF";
      
      this.axiom = "[X]++[X]++[X]++[X]++[X]";
      this.rule = "F+F-F";
      this.production = "";
    
      this.startLength = 460.0;
      this.theta = radians(36);  
      
      this.generations = 0;
    
      
      this.reset = function() {
        this.production = this.axiom;
        this.drawLength = this.startLength;
        this.generations = 0;
      }
    
      this.reset();
    
      this.getAge = function() {
        return this.generations;
      }
    
      this.iterate = function(prod_,rule_) {
        var newProduction = "";
        for (var i = 0; i < prod_.length; i++) {
          var step = this.production.charAt(i);
          if (step == 'W') {
            newProduction = newProduction + this.ruleW;
          } 
          else if (step == 'X') {
            newProduction = newProduction + this.ruleX;
          }
          else if (step == 'Y') {
            newProduction = newProduction + this.ruleY;
          }  
          else if (step == 'Z') {
            newProduction = newProduction + this.ruleZ;
          } 
          else {
            if (step != 'F') {
              newProduction = newProduction + step;
            }
          }
        }
    
        this.drawLength = this.drawLength * 0.5;
        this.generations++;
        return newProduction;
      }
      
      this.simulate = function(gen) {
        while (this.getAge() < gen) {
          this.production = this.iterate(this.production, this.rule);
        }
      }
    
      this.render = function() {
        translate(width/2, height/2);
        var pushes = 0;
        var repeats = 1;
        this.steps += 12;          
        if (this.steps > this.production.length) {
          this.steps = this.production.length;
        }
    
        for (var i = 0; i < this.steps; i++) {
          var step = this.production.charAt(i);
          var stepCode = this.production.charCodeAt(i);
          if (step == 'F') {
            stroke(255, 60);
            for (var j = 0; j < repeats; j++) {
              line(0, 0, 0, -this.drawLength);
              noFill();
              translate(0, -this.drawLength);
            }
            repeats = 1;
          } 
          else if (step == '+') {
              rotate(this.theta * repeats);
            repeats = 1;
          } 
          else if (step == '-') {
              rotate(-this.theta * repeats);
            repeats = 1;
          } 
          else if (step == '[') {
            pushes++;            
            //pushMatrix();
            push();
          } 
          else if (step == ']') {
            //popMatrix();
            pop();
            pushes--;
          } 
          else if ( (stepCode >= 48) && (stepCode <= 57) ) {
            repeats = stepCode - 48;
          }
        }
    
        // Unpush if we need too
        while (pushes > 0) {
          // popMatrix();
          pop();
          pushes--;
        }
      }
    
    
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.4/p5.min.js"></script>

    Penrose aperiodic tile using L-System