1. Define a function
sprout that moves the
and back by a small amount. In CoffeeScript, the
notation defines a function, and lining up the indent is important.
sprout = (size) -> # define sprout: a function with one parameter fd size # move forward by that amount bk size # backward by the same amount, end the function pen green # use green sprout 30 # run sprout with size 30
2. The function
sprout can be used anywhere,
including inside other functions. Try this:
sprout = (size) -> fd size bk size tree = (size) -> # tree is another function with one parameter fd size # go forward by the size lt 30 # left turn by 30 degrees sprout size * 0.7 # draw a sprout with 70% of the size rt 60 # right turn by 60 degrees sprout size * 0.7 # draw another sprout at 70% lt 30 # left turn by 30 degrees bk size # backward by size, and end the function pen green tree 30 # call tree instead of sprout
Notice how the parameter
size has a different meaning
inside each function call. Inside the call to
size is 30, but inside
size is 30 * 0.7 = 21.
3. Use an
if so that a small tree is just a
sprout, and draw a couple trees.
tree is called,
size has another value: first 9 (which triggers the
if size < 10, and then 30 (which does not).
sprout = (size) -> fd size bk size tree = (size) -> if size < 10 # do the following only if size is less than 10 sprout size # draw a sprout return # finish and return out of the function fd size lt 30 sprout size * 0.7 rt 60 sprout size * 0.7 lt 30 bk size pen green tree 9 # draw a little tree jump 50, 0 # jump 50 to the right tree 30 # draw a bigger tree
4. How can we add branches to our branches? Make a tree out of smaller trees instead of sprouts:
sprout = (size) -> fd size bk size tree = (size) -> if size < 10 # this "if" defines the important "base case" sprout size # drawing a sprout instead of a tree when size < 10 return # it prevents tree from calling itself forever fd size lt 30 tree size * 0.7 # a function can call itself! rt 60 tree size * 0.7 # experient by removing one of these. lt 30 bk size pen green tree 9 jump 50, 0 tree 30
When a function calls itself, it is
called recursion. Again, the parameter
has a different meaning each time
tree is called.
treeis called for the tiny tree,
sizeis 9, and it draws a sprout.
treeis called for the bigger tree,
sizeis 30, and it draws a trunk and calls itself.
treecalls itself again for the big branches,
sizeis 30 * 0.7 = 21.
treeis called yet again for the smaller branches,
sizeis 21 * 0.7 = 14.7
sizeis 9.87, which is the base case because size < 10, and it draws a sprout.
Notice that the 14.7 size tree draws two sprouts, and the 21 size tree draws two 14.7 size trees (making four sprouts on its branches). How many sprouts are there in total on a 30 size tree? The base case with size < 10 is important: without it, this program would never stop.
5. Add some randomness to make the tree seem more natural.
random() returns a different
random decimal number betwen 0 and 1 each time it is called.
sprout = (size) -> fd size bk size tree = (size) -> if size < 10 sprout size return fd size lt 30 tree size * (0.6 + 0.2 * random()) # random between 0.6 and 0.8 rt 60 tree size * (0.6 + 0.2 * random()) # different each time lt 30 bk size pen green tree 50