## Lindenmayer Systems using Python

21.12.2007 by Kerim in natural | python | Algorithms

A few days ago i posted some code to create screens with stars and galaxies. Today i introduce a new part usable for creating Lindenmayer Systems.

Here the rendering of a penrose tiling using my module:

### Just a short introduction:

A Lindenmayer System is a "grammar" that is defined by

- a certain vocabulary consisting mostly of single characters (like 'F', 'f' etc)
- a mapping of characters to actions (eg. "F" = draw forward, "-" = turn left, "+" = turn right)
- a substitution rule for these characters
- a starting axiom

What happens is that you will apply the substitution rules for a certain number of iterations on the axiom and the results of that axiom.

Got interested ? See this link for more information about what that a Lindenmayer System is en detail and what you can do with it.

### Code

I only quote the method that does the trick here. rendering is done via the turtle module.

def iterate(self,axiom=None, rules=None, repetitions=1): if axiom==None or rules==None: return for repeat in range(0,repetitions): newpath="" i=0 while i<len(axiom): found=False for old,new in rules: if old==axiom[i:i+len(old)]: newpath+=new i+=len(old) found=True continue if not found: newpath+=axiom[i:i+1] i+=1 axiom=newpath return axiom

A first version of the code can be downloaded here. It also includes the starfieldcode mentioned here. Please be advised that it all is still messed up a bit (as usual). If you have an idea for the for loop, tell me ;)

Honorable mention goes to the python-forum where i found that wonderful piece of code that finally showed me some cool reason to use lambdas. Calling methods in a dictionary ... fantastic:

methodToCall = {'F':lambda:self.drawForward(length), 'A':lambda:self.drawForward(length), 'B':lambda:self.drawForward(length), 'f':lambda:self.nonDrawForward(length), '-':lambda:self.turn(angle,False), '+':lambda:self.turn(angle), '|':lambda:self.turn(180), '[':lambda:stack.append(self.getState()), ']':lambda:self.setState(stack.pop()) } for char in path: try: methodToCall[char]() except: pass

If you want to play around see lsystemtest.py. There are several LSystems usable here (look for the set...functions). In the init-function directly after initializing the LSystem one is called. Simply replace the called function with a different one.

### Gallery & Feedback

I would welcome any **new** rules and renderings you create. Just mail (rules + picture) them to kmansourADDwebDOTde.

I have set up some gallery where you will find all images i create myself or get from you.

I also would like to hear new ideas (variable angles, or drawing length, colors) etc.

comments powered by Disqus