# CgTalk Maxscript Challenge 016: "L-Systems!"

#6

I’m having trouble now going into 3D representations

Idea:
After doing the replacement via recursive stringreplacement
we could parse the string letter by letter and point to a differnt function to build the visual representation.

Though I forgot that i token could be build of more than one letter like +F or -F.
Regex could help here, mabye.

Georg

#7

Thanks Rivendale, that will probably do the trick!

Great stuff rdg! Thanks. Can you post that link over at the geometrical calculations thread? I’d do it, but I want you to have the kudos!

#8

This could be done via some kind of turtle code. Check out the Complexity blog: http://www.scriptable.com/blog/complexity/

He’s done a few versions with flash actionscript.

#9

Here’s my progression so far. Right now I think I have the interpretation of the rule wrong, but it’s a start:

WARNING: Don’t increase the iteration value!!!

``````brAngle = 22.5
brLength= 5
tempLength = 0
START = "F"
rule="FF-[-F+F+F]+[+F-F-F]+FF+[+F-F-F]-[-F+F+F]"
--rule = "F+F--F+F"
anglePos = [0,0,0]
storePos = [0,0,0]
tempPos =[0,0,0]
endBranch  = #(storePos)

fn calcLSystem ruleStr iter =
(
tempString = ruleStr
for i = 1 to iter do
(
ruleStrLength = ruleStr.count
for p = 1 to ruleStrLength do
(
if tempString[p]  == "F" then ruleStr = replace ruleStr i 1 ruleStr
)
)
print ruleStr
ruleStr
)

fn newAngle ang =
(
theta = ang
phi = 90 - theta

x = cos(theta) * brLength
y = sin(theta) * brLength
z = sin(theta) * brLength * cos(phi)

[0,y,0]
)

newSpline = splineShape()
addKnot newSpline 1 #smooth #curve storePos
storePos  += [0,0,brLength]
addKnot newSpline 1 #smooth #curve (storePos )

--rule = calcLSystem rule 1
branchCount = endBranch.count
q = 0
while not (q == 24) do
(
q +=1
storePos = endBranch[q]
anglePos = [0,0,0]
for x = 1 to rule.count do
(
case rule[x] of
(
"-" : anglePos += newAngle (brAngle*-1) --calculate right
"+" : anglePos += newAngle (brAngle) --calculate left

"F" : ( --go forward
newSpline = splineShape()
addKnot newSpline 1 #smooth #curve storePos
storePos  += ([0,0,brLength] + anglePos)
addKnot newSpline 1 #smooth #curve (storePos )
brLength/= 1.1
)
"[" : ( --remember branching point
tempPos = storePos
tempLength = brLength
)
"]" : ( --go back to branching point
append endBranch storePos
--branchCount = endBranch.count
storePos = tempPos
brLength= tempLength

)

)

)

)

``````

#10

I wish I could participate in these challenges, but I’m not a worthy programmer. I applaude all your guys efforts. I wanted to show you guys a link to an article by a guy who created an ecosystem using proceedural means in houdini. This is an example of taking your guys l-system stuff to the extreme, and I hope it inspires someone out there.

http://www.highend3d.com/articles/references/Ecosystem-simulation-in-Houdini-28.html

#11

Hey Stephen, thanks! And if you’re worried about not doing so well in the challenges, we do the occasional “Back to Basics” challenges which allow people just starting up in Maxscript time to experiment.

#12

i’ll be waiting for those " back to basics" challenges …

#13

Here’s my stuff.

``````
(

fn laine pointA pointB =

(

ss = SplineShape pos:pointA

addKnot ss 1 #corner #line PointA

addKnot ss 1 #corner #line PointB

ss

)

-- Koch variant which only uses right angles

rollout kochmain1 "Koch 1"

(

spinner spn_nmax "Iterations:" type:#integer range:[0,100,0] align:#center

spinner spn_angle "Angle:" type:#integer range:[1,180,90] align:#center

button btn_doit "Do it" align:#center

progressBar doit_prog "" align:#center

on btn_doit pressed do

(

-- L-System variable related declaration

seed(timestamp())

t_start=timestamp()

doit_prog.value=0

n=0 -- Current iteration

seq="F" -- Axiom

-- Construct L-system string

for n=0 to spn_nmax.value do

(

seqtemp=""

for i=1 to seq.count do

(

case of

(

(seq[i]=="F"):

(

if n==0 then seqtemp=seq

else

(

seqtemp=seqtemp+"F+F-F-F+F"

)

)

(seq[i]=="+"):

(

seqtemp=seqtemp+"+"

)

(seq[i]=="-"):

(

seqtemp=seqtemp+"-"

)

)

)

doit_prog.value = 100.*n/spn_nmax.value

seq=seqtemp

)

t_end=timestamp()

print ("L-System string took " + ((t_end - t_start) / 1000.0) as string + " seconds")

-- L-system constructed

--Begin visual representation of L-system

seed(timestamp())

t_start=timestamp()

doit_prog.value=0

suspendEditing() -- Disable Modify Panel to make creation faster

delete \$Koch1_* --Delete previous Koch geometry

length=10

angle=spn_angle.value

roda_left=false

roda_right=false

lx=0 -- Last X Point

ly=0 -- Last Y Point

lz=0 -- Last Z Point

af=0 -- Angle Facing

for i=1 to seq.count do

(

case of

(

(seq[i]=="F"):

(

nx=lx+(length*cos(af))

ny=ly+(length*sin(af))

nz=lz

newshape=laine [lx,ly,lz] [nx,ny,nz]

select newshape

newshape.name=uniquename "Koch1_"

newshape.render_displayRenderMesh=true

newshape.wirecolor=white

lx=nx

ly=ny

lz=nz

roda_left=false

roda_right=false

)

(seq[i]=="+"):

(

af+=angle

roda_left=true;

)

(seq[i]=="-"):

(

af-=angle

roda_right=true

)

)

doit_prog.value = 100.*i/seq.count

)

resumeEditing() -- Enable Modify Panel

clearSelection()

max zoomext sel all

t_end=timestamp()

print ("L-System graphic took " + ((t_end - t_start) / 1000.0) as string + " seconds")

-- End visual representation of L-System

-- End Koch

)

)

rollout kochmain2 "Koch 2"

(

spinner spn_nmax "Iterations:" type:#integer range:[0,100,0] align:#center

spinner spn_angle "Angle:" type:#integer range:[1,180,90] align:#center

button btn_doit "Do it" align:#center

progressBar doit_prog "" align:#center

on btn_doit pressed do

(

-- L-System variable related declaration

seed(timestamp())

t_start=timestamp()

doit_prog.value=0

n=0 -- Current iteration

seq="F-F-F-F" -- Axiom

-- Construct L-system string

for n=0 to spn_nmax.value do

(

seqtemp=""

for i=1 to seq.count do

(

case of

(

(seq[i]=="F"):

(

if n==0 then seqtemp=seq

else

(

seqtemp=seqtemp+"F-F+F+FF-F-F+F"

)

)

(seq[i]=="+"):

(

seqtemp=seqtemp+"+"

)

(seq[i]=="-"):

(

seqtemp=seqtemp+"-"

)

)

)

doit_prog.value = 100.*n/spn_nmax.value

seq=seqtemp

)

t_end=timestamp()

print ("L-System string took " + ((t_end - t_start) / 1000.0) as string + " seconds")

-- L-system constructed

--Begin visual representation of L-system

seed(timestamp())

t_start=timestamp()

doit_prog.value=0

suspendEditing() -- Disable Modify Panel to make creation faster

delete \$Koch2_* --Delete previous Koch geometry

length=10

angle=spn_angle.value

roda_left=false

roda_right=false

lx=0 -- Last X Point

ly=0 -- Last Y Point

lz=0 -- Last Z Point

af=0 -- Angle Facing

for i=1 to seq.count do

(

case of

(

(seq[i]=="F"):

(

nx=lx+(length*cos(af))

ny=ly+(length*sin(af))

nz=lz

newshape=laine [lx,ly,lz] [nx,ny,nz]

select newshape

newshape.name=uniquename "Koch2_"

newshape.render_displayRenderMesh=true

newshape.wirecolor=white

lx=nx

ly=ny

lz=nz

roda_left=false

roda_right=false

)

(seq[i]=="+"):

(

af+=angle

roda_left=true;

)

(seq[i]=="-"):

(

af-=angle

roda_right=true

)

)

doit_prog.value = 100.*i/seq.count

)

resumeEditing() -- Enable Modify Panel

clearSelection()

max zoomext sel all

t_end=timestamp()

print ("L-System graphic took " + ((t_end - t_start) / 1000.0) as string + " seconds")

-- End visual representation of L-System

-- End Koch

)

)

-- Bracketed OL System

rollout brackmain1 "Bracketed OL System 1"

(

spinner spn_nmax "Iterations:" type:#integer range:[0,100,0] align:#center

spinner spn_angle "Angle:" type:#integer range:[1,180,26] align:#center

button btn_doit "Do it" align:#center

progressBar doit_prog "" align:#center

on btn_doit pressed do

(

-- L-System variable related declaration

seed(timestamp())

t_start=timestamp()

doit_prog.value=0

n=0 -- Current iteration

seq="F" -- Axiom

-- Construct L-system string

for n=0 to spn_nmax.value do

(

seqtemp=""

for i=1 to seq.count do

(

case of

(

(seq[i]=="F"):

(

if n==0 then seqtemp=seq

else

(

seqtemp=seqtemp+"FF-[-F+F+F]+[+F-F-F]"

)

)

(seq[i]=="+"):

(

seqtemp=seqtemp+"+"

)

(seq[i]=="-"):

(

seqtemp=seqtemp+"-"

)

(seq[i]=="["):

(

seqtemp=seqtemp+"["

)

(seq[i]=="]"):

(

seqtemp=seqtemp+"]"

)

)

)

doit_prog.value = 100.*n/spn_nmax.value

seq=seqtemp

)

t_end=timestamp()

print ("L-System string took " + ((t_end - t_start) / 1000.0) as string + " seconds")

-- L-system constructed

--Begin visual representation of L-system

seed(timestamp())

t_start=timestamp()

doit_prog.value=0

suspendEditing() -- Disable Modify Panel to make creation faster

delete \$Branch1_* --Delete previous Koch geometry

length=10

angle=spn_angle.value

roda_left=false

roda_right=false

lx=0 -- Last X Point

ly=0 -- Last Y Point

lz=0 -- Last Z Point

af=90 -- Angle Facing

stack_af=#()

stack_x=#()

stack_y=#()

stack_z=#()

for i=1 to seq.count do

(

case of

(

(seq[i]=="F"):

(

nx=lx+(length*cos(af))

ny=ly+(length*sin(af))

nz=lz

newshape=laine [lx,ly,lz] [nx,ny,nz]

select newshape

newshape.name=uniquename "Branch1_"

newshape.render_displayRenderMesh=true

newshape.wirecolor=white

lx=nx

ly=ny

lz=nz

roda_left=false

roda_right=false

)

(seq[i]=="+"):

(

af+=angle

roda_left=true;

)

(seq[i]=="-"):

(

af-=angle

roda_right=true

)

(seq[i]=="["):

(

append stack_af af

append stack_x lx

append stack_y ly

append stack_z lz

)

(seq[i]=="]"):

(

af=stack_af[stack_af.count]

lx=stack_x[stack_x.count]

ly=stack_y[stack_y.count]

lz=stack_z[stack_z.count]

deleteItem stack_af stack_af.count

deleteItem stack_x stack_x.count

deleteItem stack_y stack_y.count

deleteItem stack_z stack_z.count

)

)

doit_prog.value = 100.*i/seq.count

)

resumeEditing() -- Enable Modify Panel

clearSelection()

max zoomext sel all

t_end=timestamp()

print ("L-System graphic took " + ((t_end - t_start) / 1000.0) as string + " seconds")

-- End visual representation of L-System

-- End Koch

)

)

(

label lbl_label1 "by Artur Leão for CGTalk Maxscript Challenge" align:#center

)

try

(

closerolloutfloater lsystemsfloater

)

catch()

lsystemsfloater = NewRolloutFloater "L-Systems" 300 435

)

``````

#14

Awesome stuff kameleon! Nice and succint!
Okay people, let’s wrap this one up… any more gems?

#15

Thanks erilaz! Here’s my “final” version, with one more system using all three axes and with a little more pen commands. Hope you enjoy. Until the next challenge hehe

``````(
fn laine pointA pointB =
(
ss=SplineShape pos:pointA
addKnot ss 1 #corner #line PointA
addKnot ss 1 #corner #line PointB
ss
)
-- Koch variant which only uses right angles
rollout kochmain1 "Koch 1"
(
spinner spn_nmax "Iterations:" type:#integer range:[0,100,0] align:#center
spinner spn_angle "Angle:" type:#integer range:[1,180,90] align:#center
button btn_doit "Do it" align:#center
progressBar doit_prog "" align:#center

on btn_doit pressed do
(

-- L-System variable related declaration
seed(timestamp())
t_start=timestamp()
doit_prog.value=0

n=0 -- Current iteration
seq="F" -- Axiom

-- Construct L-system string
for n=0 to spn_nmax.value do
(
seqtemp=""
for i=1 to seq.count do
(
case of
(
(seq[i]=="F"):
(
if n==0 then seqtemp=seq
else
(
seqtemp=seqtemp+"F+F-F-F+F"
)
)
(seq[i]=="+"):
(
seqtemp=seqtemp+"+"
)
(seq[i]=="-"):
(
seqtemp=seqtemp+"-"
)
)
)
doit_prog.value = 100.*n/spn_nmax.value
seq=seqtemp
)
t_end=timestamp()
print ("L-System string took " + ((t_end - t_start) / 1000.0) as string + " seconds")
-- L-system constructed

--Begin visual representation of L-system
seed(timestamp())
t_start=timestamp()
doit_prog.value=0

suspendEditing() -- Disable Modify Panel to make creation faster

delete \$Koch1_* --Delete previous Koch geometry
length=10
angle=spn_angle.value

roda_left=false
roda_right=false
lx=0 -- Last X Point
ly=0 -- Last Y Point
lz=0 -- Last Z Point
af=0 -- Angle Facing
for i=1 to seq.count do
(
case of
(
(seq[i]=="F"):
(
nx=lx+(length*cos(af))
ny=ly+(length*sin(af))
nz=lz
newshape=laine [lx,ly,lz] [nx,ny,nz]
select newshape
newshape.name=uniquename "Koch1_"
newshape.render_displayRenderMesh=true
newshape.wirecolor=white
lx=nx
ly=ny
lz=nz
roda_left=false
roda_right=false
)
(seq[i]=="+"):
(
af+=angle
roda_left=true;
)
(seq[i]=="-"):
(
af-=angle
roda_right=true
)
)
doit_prog.value = 100.*i/seq.count
)
resumeEditing() -- Enable Modify Panel

clearSelection()
max zoomext sel all

t_end=timestamp()
print ("L-System graphic took " + ((t_end - t_start) / 1000.0) as string + " seconds")
-- End visual representation of L-System
-- End Koch
)
)
rollout kochmain2 "Koch 2"
(
spinner spn_nmax "Iterations:" type:#integer range:[0,100,0] align:#center
spinner spn_angle "Angle:" type:#integer range:[1,180,90] align:#center
button btn_doit "Do it" align:#center
progressBar doit_prog "" align:#center

on btn_doit pressed do
(

-- L-System variable related declaration
seed(timestamp())
t_start=timestamp()
doit_prog.value=0

n=0 -- Current iteration
seq="F-F-F-F" -- Axiom

-- Construct L-system string
for n=0 to spn_nmax.value do
(
seqtemp=""
for i=1 to seq.count do
(
case of
(
(seq[i]=="F"):
(
if n==0 then seqtemp=seq
else
(
seqtemp=seqtemp+"F-F+F+FF-F-F+F"
)
)
(seq[i]=="+"):
(
seqtemp=seqtemp+"+"
)
(seq[i]=="-"):
(
seqtemp=seqtemp+"-"
)
)
)
doit_prog.value = 100.*n/spn_nmax.value
seq=seqtemp
)
t_end=timestamp()
print ("L-System string took " + ((t_end - t_start) / 1000.0) as string + " seconds")
-- L-system constructed

--Begin visual representation of L-system
seed(timestamp())
t_start=timestamp()
doit_prog.value=0

suspendEditing() -- Disable Modify Panel to make creation faster

delete \$Koch2_* --Delete previous Koch geometry
length=10
angle=spn_angle.value

roda_left=false
roda_right=false
lx=0 -- Last X Point
ly=0 -- Last Y Point
lz=0 -- Last Z Point
af=0 -- Angle Facing
for i=1 to seq.count do
(
case of
(
(seq[i]=="F"):
(
nx=lx+(length*cos(af))
ny=ly+(length*sin(af))
nz=lz
newshape=laine [lx,ly,lz] [nx,ny,nz]
select newshape
newshape.name=uniquename "Koch2_"
newshape.render_displayRenderMesh=true
newshape.wirecolor=white
lx=nx
ly=ny
lz=nz
roda_left=false
roda_right=false
)
(seq[i]=="+"):
(
af+=angle
roda_left=true;
)
(seq[i]=="-"):
(
af-=angle
roda_right=true
)
)
doit_prog.value = 100.*i/seq.count
)
resumeEditing() -- Enable Modify Panel

clearSelection()
max zoomext sel all

t_end=timestamp()
print ("L-System graphic took " + ((t_end - t_start) / 1000.0) as string + " seconds")
-- End visual representation of L-System
-- End Koch
)
)
-- Bracketed OL System
rollout brackmain1 "Bracketed OL System 1"
(
spinner spn_nmax "Iterations:" type:#integer range:[0,100,0] align:#center
spinner spn_angle "Angle:" type:#integer range:[1,180,26] align:#center
button btn_doit "Do it" align:#center
progressBar doit_prog "" align:#center

on btn_doit pressed do
(

-- L-System variable related declaration
seed(timestamp())
t_start=timestamp()
doit_prog.value=0

n=0 -- Current iteration
seq="F" -- Axiom

-- Construct L-system string
for n=0 to spn_nmax.value do
(
seqtemp=""
for i=1 to seq.count do
(
case of
(
(seq[i]=="F"):
(
if n==0 then seqtemp=seq
else
(
seqtemp=seqtemp+"FF-[-F+F+F]+[+F-F-F]"
)
)
(seq[i]=="+"):
(
seqtemp=seqtemp+"+"
)
(seq[i]=="-"):
(
seqtemp=seqtemp+"-"
)
(seq[i]=="["):
(
seqtemp=seqtemp+"["
)
(seq[i]=="]"):
(
seqtemp=seqtemp+"]"
)
)
)
doit_prog.value = 100.*n/spn_nmax.value
seq=seqtemp
)
t_end=timestamp()
print ("L-System string took " + ((t_end - t_start) / 1000.0) as string + " seconds")
-- L-system constructed

--Begin visual representation of L-system
seed(timestamp())
t_start=timestamp()
doit_prog.value=0

suspendEditing() -- Disable Modify Panel to make creation faster

delete \$Branch1_* --Delete previous Koch geometry
length=10
angle=spn_angle.value

roda_left=false
roda_right=false
lx=0 -- Last X Point
ly=0 -- Last Y Point
lz=0 -- Last Z Point
af=90 -- Angle Facing
stack_af=#()
stack_x=#()
stack_y=#()
stack_z=#()
for i=1 to seq.count do
(
case of
(
(seq[i]=="F"):
(
nx=lx+(length*cos(af))
ny=ly+(length*sin(af))
nz=lz
newshape=laine [lx,ly,lz] [nx,ny,nz]
select newshape
newshape.name=uniquename "Branch1_"
newshape.render_displayRenderMesh=true
newshape.wirecolor=white
lx=nx
ly=ny
lz=nz
roda_left=false
roda_right=false
)
(seq[i]=="+"):
(
af+=angle
roda_left=true;
)
(seq[i]=="-"):
(
af-=angle
roda_right=true
)
(seq[i]=="["):
(
append stack_af af
append stack_x lx
append stack_y ly
append stack_z lz
)
(seq[i]=="]"):
(
af=stack_af[stack_af.count]
lx=stack_x[stack_x.count]
ly=stack_y[stack_y.count]
lz=stack_z[stack_z.count]
deleteItem stack_af stack_af.count
deleteItem stack_x stack_x.count
deleteItem stack_y stack_y.count
deleteItem stack_z stack_z.count
)
)
doit_prog.value = 100.*i/seq.count
)
resumeEditing() -- Enable Modify Panel

clearSelection()
max zoomext sel all

t_end=timestamp()
print ("L-System graphic took " + ((t_end - t_start) / 1000.0) as string + " seconds")
-- End visual representation of L-System
-- End Koch
)
)
-- Bush
rollout bushmain1 "Bush 1"
(
spinner spn_nmax "Iterations:" type:#integer range:[0,100,0] align:#center
spinner spn_angle "Angle:" type:#integer range:[1,180,26] align:#center
button btn_doit "Do it" align:#center
progressBar doit_prog "" align:#center

on btn_doit pressed do
(

-- L-System variable related declaration
seed(timestamp())
t_start=timestamp()
doit_prog.value=0

n=0 -- Current iteration
seq="F" -- Axiom

-- Construct L-system string
for n=0 to spn_nmax.value do
(
seqtemp=""
for i=1 to seq.count do
(
case of
(
(seq[i]=="F"):
(
if n==0 then seqtemp=seq
else
(
seqtemp=seqtemp+"F-[F\\F+F&F]/[F[-F]^F]/F"
)
)
default:
(
seqtemp=seqtemp+seq[i]
)
)
)
doit_prog.value = 100.*n/spn_nmax.value
seq=seqtemp
)
t_end=timestamp()
print ("L-System string took " + ((t_end - t_start) / 1000.0) as string + " seconds")
-- L-system constructed
--Begin visual representation of L-system
try
(
seed(timestamp())
t_start=timestamp()
doit_prog.value=0

suspendEditing which:#modify alwaysSuspend:true -- Disable Modify Panel to make creation faster

delete \$Bush1_* --Delete previous Koch geometry

angle=spn_angle.value
blength=10
afx=90
afy=0
afz=90
lpx=0
lpy=0
lpz=0
npx=0
npy=0
npz=0
stack_afx=#()
stack_afy=#()
stack_afz=#()
stack_x=#()
stack_y=#()
stack_z=#()
for i=1 to seq.count do
(
case of
(
(seq[i]=="F"):
(
npx=lpx+(blength*cos(afx))
npy=lpy+(blength*sin(afy))
phi=90-afz
npz=lpz+(sin(afz)*blength*cos(phi))
newshape=laine [lpx,lpy,lpz] [npx,npy,npz]
select newshape
newshape.name=uniquename "Bush1_"
newshape.render_displayRenderMesh=true
newshape.render_sides=4
newshape.wirecolor=white
lpx=npx
lpy=npy
lpz=npz
)
(seq[i]=="+"):
(
afx+=angle
afy+=angle
)
(seq[i]=="-"):
(
afx-=angle
afy-=angle
)
(seq[i]=="\\"):
(
afx+=angle
afz+=angle
)
(seq[i]=="/"):
(
afx-=angle
afz-=angle
)
(seq[i]=="&"):
(
afy+=angle
afz+=angle
)
(seq[i]=="^"):
(
afy-=angle
afz-=angle
)
(seq[i]=="|"):
(
afx+=90-afx
afy+=0
afz+=90
)
(seq[i]=="["):
(
append stack_afx afx
append stack_afy afy
append stack_afz afz
append stack_x lpx
append stack_y lpy
append stack_z lpz
)
(seq[i]=="]"):
(
afx=stack_afx[stack_afx.count]
afy=stack_afy[stack_afy.count]
afz=stack_afz[stack_afz.count]
lpx=stack_x[stack_x.count]
lpy=stack_y[stack_y.count]
lpz=stack_z[stack_z.count]
deleteItem stack_afx stack_afx.count
deleteItem stack_afy stack_afy.count
deleteItem stack_afz stack_afz.count
deleteItem stack_x stack_x.count
deleteItem stack_y stack_y.count
deleteItem stack_z stack_z.count
)
)
doit_prog.value = 100.*i/seq.count
)
clearSelection()
max zoomext sel all

t_end=timestamp()
print ("L-System graphic took " + ((t_end - t_start) / 1000.0) as string + " seconds")
throw "Done"
)
catch
(
resumeEditing which:#modify alwaysSuspend:true-- Enable Modify Panel
)
)
)
(
label lbl_label1 "by Artur Leão for CGTalk Maxscript Challenge" align:#center
)
try
(
closerolloutfloater lsystemsfloater
) catch()
lsystemsfloater = NewRolloutFloater "L-Systems" 300 555

)

``````

And a simple image created with the last system.

#16

hey now we’re talking! let me just find a few hours LOL

keep thi sone open for a while Mr monkey

J.

#17

This one will be kept open probably another week, so go for it j-man!

#18

go! j-man go!

Georg

#19

no cigar but I have a consolation fro anyone into this kind of stuff:

[font=Arial]http://www.btinternet.com/~ndesprez/index.htm

enjoy!

J.

[/font]

#20

Heh… thanks J-man.

I’ll be starting a new challenge this week.

#21

Hi every1
Although v. late, but I also wanted to join in the fun.
This is a simple code which displays a 2D representation of the plant. The site (http://algorithmicbotany.org/papers/) pointed by Georg was v. helpful.
Still needs a lot of work (thickness, color, 3D etc) and im working on it.

``````
--Plant Generator
--Author: Bhupendra Aole
--Dated: 29-Feb-08
--Version: 1.0
--Research: http://algorithmicbotany.org/papers/
--Concept:
--  Lindenmayer systems  or L-systems for short
--  The central concept of L-systems is that of rewriting. In general, rewriting
--  is a technique for defining complex objects by successively replacing
--  parts of a simple initial object using a set of rewriting rules or productions.
--Legends:
--  F: Draw a line of unit length from current position in current direction
--  +: increase angle
--  -: decrease angle
--  [: push the current state (pos, orientation)
--  ]: pop the last state and make it current
--Wish list:
--  1. node writing
--  2. extend to 3D
--  3. use colors
--  4. provide thickness
--  5. wield vertices
--Code Version: 0.7

-- simple stack implementation
struct bstack (
s = #(),
fn pop = (
val = s[s.count]
deleteItem s s.count
val
),
fn push val = (
append s val
)
)

-- build expression for no. of iterations
fn buildExp axiom rep iter = (
ret = copy axiom -- this is the first iteration itself
str = ""
for i=2 to iter do ( -- if iterations gr8er than 1
for c = 1 to ret.count do ( -- loop thru' the exp
if (ret[c] == axiom) then ( -- if rule found
append str rep
) else ( -- just add the rest
append str ret[c]
)
)
ret = copy str
str = ""
)
ret
)

-- functions for creating spline
global ss
fn startLine point = (
ss = SplineShape pos:point
)
(
addKnot ss i #corner #line PointA
addKnot ss i #corner #line PointB
)
fn endLine = (
)

-- evaluate expression and draw plant
fn visualize exp ang = (
posStk = bstack ()

-- to be UIed
pStart = [0,0,0]
pLen = 10
delta = ang
--

curPos = copy pStart
curAng = 0

startLine curPos

for c = 1 to exp.count do (
if (exp[c] == "F") then (

curPos = nextPos
) else if (exp[c] == "+") then (
curAng += delta
) else if (exp[c] == "-") then (
curAng -= delta
) else if (exp[c] == "[") then (
posStk.push (copy curPos)
) else if (exp[c] == "]") then (
curPos = posStk.pop ()
)
)

endLine()
)

-- provide expression and call visualize
fn buildTree = (
-- expressions that produce good results
-- F[+F]F[-F]F (25.7)
-- F[+F]F[-F][F] (20)
-- FF-[-F+F+F]+[+F-F-F] (22.5)

-- only use 'F' variable in the expression
e = buildExp "F" "F[+F]F[-F]F" 5
visualize e 25.5
)

-- test
buildTree()

``````

Thanks,
Bhupendra

#22

IMHO, lovely clean script, clean thinking. Even though it’s ‘late’, I’m looking forward to seeing where it goes!

#23

Hi

thanks Robin!

``````Extended the code to 3D, but am unhappy with the results.
Cant figure out y the code is not behaving the way it should ... giving somwhat wierd results.
``````
``````
--==================================================================================
--Plant Generator
--Author: Bhupendra Aole
--Dated: 29-Feb-08
--Version: 1.2
--Revision:
--  1.1: 1-mar-8: Implemented Node writing
--  1.2: 4-mar-8: Extend to 3D, added special procedure to create leaves
--Research: http://algorithmicbotany.org/papers/
--Concept:
--  Lindenmayer systems  or L-systems for short
--  The central concept of L-systems is that of rewriting. In general, rewriting
--  is a technique for defining complex objects by successively replacing
--  parts of a simple initial object using a set of rewriting rules or productions.
--Controls:
--  F: Draw a line of unit length from current position in current direction
--  f: same as F w/o drawing
--  +: increase angle (2D)
--  -: decrease angle (2D)
--  [: push the current state (pos, orientation)
--  ]: pop the last state and make it current
--3D controls:
--  + Turn left by angle Â, using rotation matrix RU(Â).
--  - Turn right by angle Â, using rotation matrix RU(.Â).
--  & Pitch down by angle Â, using rotation matrix RL(Â).
--  ^ Pitch up by angle Â, using rotation matrix RL(.Â).
--  \ Roll left by angle Â, using rotation matrix RH(Â).
--  / Roll right by angle Â, using rotation matrix RH(.Â).
--  | Turn around, using rotation matrix RU(180).
--  { start a polygon
--  } complete a polygon
--Wish list:
--  3. use colors
--  4. provide thickness
--  5. wield vertices
--Code Version: 1.23
--Code Revision:
--	 "   : changed buildExp to handle map (more than 1 var)
--  4-mar-8: added 3d angles for movement
--	   "   : createPoly() creates "capped" surfaces bounded by vertices
--  5-mar-8: added extrude modifier to leaf before cap_holes modifier
--==================================================================================
-- simple map implementation
struct keyvalue (
k = #(),
v = #()
)
struct bMap (
entry = #(),
fn put key value = (
kv = keyvalue k:key v:value
append entry kv
),
fn get key = (
ret = undefined
for i=1 to entry.count do (
kv = entry[i]
if (kv.k == key) then (
ret = kv.v
exit
)
)
ret
)
)

-- simple stack implementation
struct bStack (
s = #(),
fn pop = (
val = s[s.count]
deleteItem s s.count
val
),
fn push val = (
append s val
),
fn empty = (
s = #()
),
fn size = (
s.count
)
)

-- build expression for no. of iterations
fn buildExp axiom rules iter = (
ret = copy axiom -- this is the first iteration itself
str = ""
for i=2 to iter do ( -- if iterations gr8er than 1
for c = 1 to ret.count do ( -- loop thru' the exp
val = rules.get ret[c]
if (val == undefined) then (
-- special chars ... just append
append str ret[c]
) else (
append str val
)
)
ret = copy str
str = ""
)
ret
)

-- functions for creating spline
global ss
fn startLine point = (
ss = SplineShape pos:point
)
(
addKnot ss i #corner #line PointA
addKnot ss i #corner #line PointB
)
fn endLine = (
)
fn createPoly stk = (
pol = SplineShape wirecolor:[0,255,0]
sz = stk.size()
if (sz>2) then (
frst = stk.pop()
addKnot pol 1 #smooth #curve frst
for i = 2 to sz do (
addKnot pol 1 #smooth #curve (stk.pop())
)
addKnot pol 1 #smooth #curve frst -- just to make sure the spline is closed (for cap modifier)
close pol 1
mod = Extrude amount:0.001 output:0
)
)
-- evaluate expression and draw plant
fn visualize exp ang = (
posStk = bstack ()
polyStk = bstack ()
lenStk = bstack ()

-- to be UIed
pStart = [0,0,0]
pLen = 10
delta = ang
--

inPoly = 0 -- lets the prog know if we r drawing a polygon
curPos = copy pStart
curXAng = 0 -- yaw
curYAng = 0 -- pitch
curZAng = 0 -- roll
xch = 0 -- angle change flags
ych = 0
zch = 0
startLine curPos

for c = 1 to exp.count do (
if (exp[c] == "+") then (
curXAng += delta
) else if (exp[c] == "-") then (
curXAng -= delta
) else if (exp[c] == "&") then (
curYAng += delta
) else if (exp[c] == "^") then (
curYAng -= delta
) else if (exp[c] == "\\") then (
curZAng += delta
) else if (exp[c] == "/") then (
curZAng -= delta
) else if (exp[c] == "|") then (
curXAng += 180
) else if (exp[c] == "[") then (
posStk.push (copy curPos)
) else if (exp[c] == "]") then (
curPos = posStk.pop ()
) else if (exp[c] == "F") then (
curPos = nextPos
) else if (exp[c] == "f") then (
curPos = nextPos
if (inPoly==1) then (
polyStk.push curPos
)
) else if (exp[c] == "{") then (
inPoly = 1
lenStk.push (copy pLen)
pLen = 7 -- make the leaf size smaller
) else if (exp[c] == "}") then (
inPoly = 0
createPoly polyStk
polyStk.empty ()
pLen = lenStk.pop ()
)
)

endLine()
)

-- provide expression and call visualize
fn buildTree = (
-- expressions that produce good results (abop.pdf pg:25)
-- F[+F]F[-F]F (25.7)
-- F[+F]F[-F][F] (20)
-- FF-[-F+F+F]+[+F-F-F] (22.5)

-- only use 'F' variable in the expression
--expr = buildExp "F" (bMap #(keyvalue "F" "F[+F]F[-F]F")) 5
--e = buildExp "X" (bMap #(keyvalue "X" "F[+X]F[-X]+X", keyvalue "F" "FF")) 7
--e = buildExp "X" (bMap #(keyvalue "X" "F[+X][-X]FX", keyvalue "F" "FF")) 7
--e = buildExp "X" (bMap #(keyvalue "X" "F-[[X]+X]+F[+FX]-X", keyvalue "F" "FF")) 6
--3D
expr = buildExp "A" (bMap #(keyvalue "A" "///BY///BYA", keyvalue "B" "[&Y[+L][-L]YBF]", keyvalue "L" "FF'{+X-X-X+|+X-X}", keyvalue "X" "fX", keyvalue "Y" "FY")) 9
visualize expr 22.5
)

-- test
buildTree()

``````

#24

Was able to generate the following plant with the expression:
expr = buildExp “A” (bMap #(keyvalue “A” “///BY///BYA”, keyvalue “B” “[&Y[+L][-L]YBF]”, keyvalue “L” “FF’{+X-X-X+|+X-X}”, keyvalue “X” “fX”, keyvalue “Y” “FY”)) 9
visualize expr 22.5

looked it up thru’: http://www.geocities.com/gplatl/LSystem/LSystem.html

-Bhupendra

#25

This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.