#### Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

# L-System Explorer: another experiment with procedural plants and gsub

edited October 2017 Posts: 489

(Updated) The inspiration for the code below is the book identified below and the Wikipedia articles on simulated growth of plants and L-systems that cite it as a source. An example of its output is below: ```--
-- L-System Explorer
--
-- With acknowledgements to "The Algorithmic Beauty of Plants" by
-- Przemyslaw Prusinkiewicz and Aristid Lindenmayer
-- http://algorithmicbotany.org/papers/

supportedOrientations(LANDSCAPE_ANY)
function setup()
-- Set up L-System
l = L("X", {X = "F-[[X]+X]+F[+FX]-X", F = "FF"}, 5, 22.5)
-- Other L-Systems:
-- l = L("F", {F = "FF-[-F+F+F]+[+F-F-F]"}, 5, 22.5)
-- l = L("X", {X = "F-[[X]+X]+F[+FX]-X", F = "FF"}, 5, 22.5)
-- l = L("X", {X = "F[+X][-X]FX", F = "FF"}, 5, 25.7)
-- l = L("X", {X = "F[+X]F[-X]+X", F = "FF"}, 5, 20)
l.color = color(50, 140, 28)

sTime = ElapsedTime
step = 1
count = 1
maxCount = 7

bm = mesh()
bm.vertices = {vec2(1, 1), vec2(WIDTH, 1), vec2(1, HEIGHT),
vec2(1, HEIGHT), vec2(WIDTH, 1), vec2(WIDTH, HEIGHT)}
local c1 = color(199, 200, 159)
local c2 = color(203, 214, 89)
bm.colors = {c2, c2, c1, c1, c2, c1}
textMode(CORNER)
font("Inconsolata")
end

function draw()
if ElapsedTime - sTime > step and count < maxCount then
l:grow()
sTime = ElapsedTime
count = count + 1
end
background(0)
bm:draw()
fill(0)
local h = HEIGHT - 30
for k, v in pairs(l.rules) do
local r = k.." -> "..v
text(r, 10, h)
h = h - 30
end

translate(WIDTH/2, 0)
l:draw()
end

L = class()

function L:init(root, rules, length, angle)
self.state = root
self.rules = rules
self.length = length
self.angle = angle
self.color = color(255)
local pattern = "(["
for k, v in pairs(rules) do
pattern = pattern..k
end
self.pattern = pattern.."])"
end

function L:draw()
local stack = {}
pushMatrix()
pushStyle()
stroke(self.color)
strokeWidth(1)
noSmooth()
local tx, ty, ta = 0, 0, 90
local l = self.length
local a = self.angle
for i = 1, #self.state do
local ntx, nty, nta
local c =self.state:sub(i, i)
if c == "F" then
nta = ta
ntx = tx + l * math.cos(nar)
nty = ty + l * math.sin(nar)
line(tx, ty, ntx, nty)
elseif c == "-" then
nta = (ta - a) % 360
ntx, nty = tx, ty
elseif c == "+" then
nta = (ta + a) % 360
ntx, nty = tx, ty
elseif c == "[" then
stack[#stack + 1] = {tx, ty, ta}
ntx, nty, nta = tx, ty, ta
elseif c == "]" then
ntx, nty, nta = unpack(stack[#stack])
table.remove(stack)
else
ntx, nty, nta = tx, ty, ta
end
tx, ty, ta = ntx, nty, nta
end
popStyle()
popMatrix()
end

function L:grow()
local function f(...)
return self.rules[arg]
end
self.state = self.state:gsub(self.pattern, f)
end
```

Elsewhere on the Codea Forum, @Herwig and @Bri_G have also posted L-system based code, here and here. This code is shorter, because it makes use of Lua's powerful `string.gsub()` library function.

The rules of the L-system are represented by a Lua table (referred to in the Codea class `L` by the by the field `rules`). For example, the two rules:

```X -> F-[[X]+X]+F[+FX]-X
F -> FF
```

are represented by the table constructed as:

```{
X = "F-[[X]+X]+F[+FX]-X",
F = "FF"
}
```
Tagged:

• Posts: 563

You are a code generating machine!

• edited October 2012 Posts: 489

Thank you @Reefwing - I'll take that as a compliment. I have updated my original post to include further references and explanations.

If anybody should follow the experiments that I post to this forum, they will see that they are only snippets. My current interest is to explore what short but, hopefully, intelligible code can produce.

• Posts: 666

So, I'd like to take this code and have it generate a mesh object...should be simple to do that...it's leaves that I don't know (yet) how to generate. I think the Bloom project will help with that...

• Posts: 563

It was a compliment @mpilgrem - I'm amazed at how much code you are able to produce on a variety of subjects.

• Posts: 2,161

@mpilgrem I'm getting curious as to your background. There's quite a lot of mathematics behind some of these things you're doing.