Notifications
Clear all

[Closed] CgTalk Maxscript Challenge 016: "L-Systems!"

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

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
addNewSpline ss
addKnot ss 1 #corner #line PointA
addKnot ss 1 #corner #line PointB
updateShape ss
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
)
)
-- Quadratic Koch island
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
)
)
)
rollout aboutmain1 "About"
(
label lbl_label1 "by Artur Leão for CGTalk Maxscript Challenge" align:#center
hyperlink hl_hp "Artur Leão Portfolio" color:(color 0 0 255) address:"[ http://dimensao3.com/al ]( http://dimensao3.com/al )" align:#center
) 
try 
(
closerolloutfloater lsystemsfloater
) catch()
lsystemsfloater = NewRolloutFloater "L-Systems" 300 555
AddRollout kochmain1 lsystemsfloater
AddRollout kochmain2 lsystemsfloater
AddRollout brackmain1 lsystemsfloater
AddRollout bushmain1 lsystemsfloater
AddRollout aboutmain1 lsystemsfloater
 
)

And a simple image created with the last system.

Download here (1280×1024)

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

keep thi sone open for a while Mr monkey

J.

1 Reply
(@erilaz)
Joined: 11 months ago

Posts: 0

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

 rdg

go! j-man go!

[insert link to your favorite cheerleader image here]

Georg

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]

1 Reply
(@erilaz)
Joined: 11 months ago

Posts: 0

Heh… thanks J-man.

I’ll be starting a new challenge this week.

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.
Any input would be helpful.


 --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
 )
 fn addLine pointA pointB =
 (
 	i = addNewSpline ss
 	addKnot ss i #corner #line PointA
 	addKnot ss i #corner #line PointB
 )
 fn endLine = (
 	updateShape ss
 )
 
 -- evaluate expression and draw plant
 fn visualize exp ang = (
 	posStk = bstack ()
 	headStk = 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 (
 			heading = matrix3 1
 			translate heading [0,0,pLen]
 			rotatex heading curAng
 			translate heading curPos
 			nextPos = pStart * heading
 
 			addLine curPos nextPos
 			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)
 			headStk.push (copy curAng)
 		) else if (exp[c] == "]") then (
 			curPos = posStk.pop ()
 			curAng = headStk.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

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

1 Reply
(@bhupendra)
Joined: 11 months ago

Posts: 0

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:
--  1-mar-8: add map implementation
--	 "   : 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
)
fn addLine pointA pointB =
(
	i = addNewSpline ss
	addKnot ss i #corner #line PointA
	addKnot ss i #corner #line PointB
)
fn endLine = (
	updateShape ss
)
fn createPoly stk = (
	pol = SplineShape wirecolor:[0,255,0]
	addNewSpline pol
	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
		updateShape pol
		mod = Extrude amount:0.001 output:0
		addModifier pol (mod)
		addModifier pol (cap_holes ())
	)
)
-- evaluate expression and draw plant
fn visualize exp ang = (
	posStk = bstack ()
	headStk = 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
	heading = matrix3 1
	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)
			headStk.push (copy curXAng)
			headStk.push (copy curYAng)
			headStk.push (copy curZAng)
		) else if (exp[c] == "]") then (
			curPos = posStk.pop ()
			curZAng = headStk.pop()
			curYAng = headStk.pop()
			curXAng = headStk.pop()
		) else if (exp[c] == "F") then (
			identity heading
			translate heading [0,0,pLen]
			rotatex heading curXAng
			rotatey heading curYAng
			rotatez heading curZAng
			translate heading curPos
			nextPos = pstart * heading
			addLine curPos nextPos
			curPos = nextPos
		) else if (exp[c] == "f") then (
			identity heading
			translate heading [0,0,pLen]
			rotatex heading curXAng
			rotatey heading curYAng
			rotatez heading curZAng
			translate heading curPos
			nextPos = pstart * heading
			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()

   

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

Page 2 / 2