Python Recursion Fractals and Visualization trees
http://interactivepython.org/runestone/static/pythonds/Recursion/pythondsintro-VisualizingRecursion.html
4.7. Introduction: Visualizing Recursion
In the previous section we looked at some problems that were easy to solve using recursion; however, it can still be difficult to find a mental model or a way of visualizing what is happening in a recursive function. This can make recursion difficult for people to grasp. In this section we will look at a couple of examples of using recursion to draw some interesting pictures. As you watch these pictures take shape you will get some new insight into the recursive process that may be helpful in cementing your understanding of recursion.The tool we will use for our illustrations is Python’s turtle graphics module called
turtle
. The turtle
module is standard with all
versions of Python and is very easy to use. The metaphor is quite
simple. You can create a turtle and the turtle can move forward,
backward, turn left, turn right, etc. The turtle can have its tail up or
down. When the turtle’s tail is down and the turtle moves it draws a
line as it moves. To increase the artistic value of the turtle you can
change the width of the tail as well as the color of the ink the tail is
dipped in.Here is a simple example to illustrate some turtle graphics basics. We will use the turtle module to draw a spiral recursively. ActiveCode 1 shows how it is done. After importing the
turtle
module we create a turtle. When the turtle is created it also creates a
window for itself to draw in. Next we define the drawSpiral function.
The base case for this simple function is when the length of the line we
want to draw, as given by the len
parameter, is reduced to zero or
less. If the length of the line is longer than zero we instruct the
turtle to go forward by len
units and then turn right 90 degrees.
The recursive step is when we call drawSpiral again with a reduced
length. At the end of ActiveCode 1 you will notice that we call
the function myWin.exitonclick()
, this is a handy little method of
the window that puts the turtle into a wait mode until you click inside
the window, after which the program cleans up and exits.
1
import turtle
2
3
myTurtle = turtle.Turtle()
4
myWin = turtle.Screen()
5
6
def drawSpiral(myTurtle, lineLen):
7
if lineLen > 0:
8
myTurtle.forward(lineLen)
9
myTurtle.right(90)
10
drawSpiral(myTurtle,lineLen-5)
11
12
drawSpiral(myTurtle,100)
13
myWin.exitonclick()
14
To understand how this is going to work it is helpful to think of how we might describe a tree using a fractal vocabulary. Remember that we said above that a fractal is something that looks the same at all different levels of magnification. If we translate this to trees and shrubs we might say that even a small twig has the same shape and characteristics as a whole tree. Using this idea we could say that a tree is a trunk, with a smaller tree going off to the right and another smaller tree going off to the left. If you think of this definition recursively it means that we will apply the recursive definition of a tree to both of the smaller left and right trees.
Let’s translate this idea to some Python code. Listing 1 shows how we can use our turtle to generate a fractal tree. Let’s look at the code a bit more closely. You will see that on lines 5 and 7 we are making a recursive call. On line 5 we make the recursive call right after the turtle turns to the right by 20 degrees; this is the right tree mentioned above. Then in line 7 the turtle makes another recursive call, but this time after turning left by 40 degrees. The reason the turtle must turn left by 40 degrees is that it needs to undo the original 20 degree turn to the right and then do an additional 20 degree turn to the left in order to draw the left tree. Also notice that each time we make a recursive call to
tree
we subtract some amount from
the branchLen
parameter; this is to make sure that the recursive
trees get smaller and smaller. You should also recognize the initial
if
statement on line 2 as a check for the base case of branchLen
getting too small.
Listing 1
1 2 3 4 5 6 7 8 9 | def tree(branchLen,t):
if branchLen > 5:
t.forward(branchLen)
t.right(20)
tree(branchLen-15,t)
t.left(40)
tree(branchLen-10,t)
t.right(20)
t.backward(branchLen)
|
1
import turtle
2
3
def tree(branchLen,t):
4
if branchLen > 5:
5
t.forward(branchLen)
6
t.right(20)
7
tree(branchLen-15,t)
8
t.left(40)
9
tree(branchLen-15,t)
10
t.right(20)
11
t.backward(branchLen)
12
13
def main():
14
t = turtle.Turtle()
15
myWin = turtle.Screen()
16
t.left(90)
17
t.up()
18
t.backward(100)
19
t.down()
20
t.color("green")
21
tree(75,t)
22
myWin.exitonclick()
23
24
main()
25
Self Check
Modify the recursive tree program using one or all of the following
ideas:- Modify the thickness of the branches so that as the
branchLen
gets smaller, the line gets thinner. - Modify the color of the branches so that as the
branchLen
gets very short it is colored like a leaf. - Modify the angle used in turning the turtle so that at each branch point the angle is selected at random in some range. For example choose the angle between 15 and 45 degrees. Play around to see what looks good.
- Modify the
branchLen
recursively so that instead of always subtracting the same amount you subtract a random amount in some range.
No hay comentarios:
Publicar un comentario