1

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)

Jerry Stratton
  • 3,287
  • 1
  • 22
  • 30
m.prcssng
  • 43
  • 1
  • 5

3 Answers3

2

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

George Profenza
  • 50,687
  • 19
  • 144
  • 218
  • Thanks for the quick advice. I will try some things out and share my code next time. – m.prcssng Apr 23 '15 at 15:16
  • @m.prcssng I've just updated my post above with an L-System snippet you run right here on the site. Feel free to vote/mark the answer if it was helpful ;) – George Profenza May 07 '15 at 21:26
1

I have tried to create a piece of code with my teacher. It's very basic, but I wanted to share the result:

String txt = "A";

for (int i = 0; i < 5; i ++) {
  println(txt);
  String newTxt = "";
  for (int j = 0; j < txt.length(); j++) {
    String letter = txt.substring(j, j+1);
    if (letter.equals("A")) {
      newTxt += "AB"; 
    } else {
      newTxt += "A"; 
    }
  }
  txt = newTxt;
}

Thanks again for the help!

m.prcssng
  • 43
  • 1
  • 5
0

Here my code using Openframework. I believe it produces the most light weight and beautiful many L-systems plants in a loop and not using any light or texture.

#include "ofMain.h"
#include "application.h"

int main( )
{
  ofSetupOpenGL(512, 512, OF_WINDOW);
  ofRunApp(new Application());
}
--------------------------
#include "renderer.h"

void Renderer::setup()
{
  ofSetFrameRate(3);
  ofSetWindowShape(kWindow_width, kWindow_height);
}

void Renderer::draw()
{
  ofFill();
  ofSetLineWidth(10);
  ofClear(0);
  ofScale(1.0f, -1.0f);
  ofTranslate(kWindow_width / 2, -kWindow_height + 75);
  ofLine(0,0,0, 300);
  angleDepart -= 1;
  splitLine(0, 300, 20, angleDepart); // faire varier le 20, en 10 et 20, c'est le plus intéressant
}

void Renderer::splitLine(int iX, int iY, int iThickness, float iAngle)
{
  if (iThickness - 1 > 0)
  {
    ofPushMatrix();
    ofTranslate(iX, iY);
    ofRotateZ(iAngle);
    ofSetLineWidth(iThickness - 1);
    ofLine(0, 0, iX * 0.75, iY * 0.75);
    splitLine(iX * 0.75, iY * 0.75, iThickness - 1, iAngle);
    ofPopMatrix();

    ofPushMatrix();
    ofLine(0, 0, iX * 0.75, iY * 0.75);
    ofSetColor(65, ofRandom(255), 0);
    splitLine(iX * 0.75, iY * 0.75, iThickness - 2, -iAngle);
    ofPopMatrix();
  }
}
----------------------------------
#pragma once
#include "ofMain.h"

class Renderer
{
public:
  void setup();
  void draw();

  int angleDepart = 0;
  const int kWindow_height = 1000;
  const int kWindow_width  = 1200;
  void splitLine(int iX, int iY, int iThickness, float angle);
};

L-System picture

capangel
  • 1
  • 1