效果图,理解本程序递归的时候请盯死它。这篇文章可以说是雪花第三弹了。
当然,这次重点不在于画画,而是在于理解好递归。即便你不会python,在我的注释的帮助下你也可以看懂这个代码(是看懂不是理解)。另外有python的同学可以打进去试试,观察完整绘画过程更有利于理解。
import turtle def tree(branchLen,t): #定义一个画画的函数,下面是重点,需要大家自行理解。 if branchLen > 6: t.forward(branchLen) #前进branchLen长度 t.right(20) #右转20° tree(branchLen-15,t) #递归 t.left(40) tree(branchLen-15,t) t.right(20) t.backward(branchLen) #后退branchLen长度 t = turtle.Turtle() #创造画笔 mytree = turtle.Screen() #显示可视化窗口 t.left(90) #转到垂直向上 t.up() #提起画笔,为了后面调整位置 t.backward(100) #调整位置 t.down() #画笔落下 t.color("blue") #调整画笔颜色 tree(90,t) #开始画画 mytree.exitonclick() #防止一画完就自动退出
可能最难理解的部分:
def tree(branchLen,t): #定义一个画画的函数,这是个重点,需要大家自行理解。 if branchLen > 6: t.forward(branchLen) t.right(20) tree(branchLen-15,t) t.left(40) tree(branchLen-15,t) t.right(20) t.backward(branchLen)
实际上通过语言形象地把递归讲好是有点难度的,这里我只能尽量解释。首先如果我们设定长度为90.那么第一个递归语句(需要说明的是,第一个递归语句是最后结束的):
tree(branchLen-15,t) t.left(40)
它一共要递归7次,只不过第七次当branchLen = 15 的时候刚好为0不满足条件。我们从这里开始。
此时的位置:
到这里为止,向左转40°
t.left(40)
就是想要画出那个分叉口,但是由于此时的branchLen = 15,当它执行第二个递归语句的时候
tree(branchLen-15,t)
发现无法满足条件,因此又右转20°并返回到原来开始画分叉的那个结点(就是第五个转方向的地点)。
这个小小小小小递归结束,回到branchLen = 30,这时候就能够执行
t.left(40) tree(branchLen-15,t) t.right(20) t.backward(branchLen)
没错,这里又进行了一次递归。因此它顺利画出分叉:
然后返回到长度为30的那一个结点,如图
此时回到上一层递归,branchLen = 45.又开始一个新的递归,然后这个新的递归里又产生了一个新递归,这个新递归又调用一次递归,最终这个递归无法满足条件回到上一个递归画出了叉口,再返回上一次递归branchLen = 60.然后又开始一个新的递归……
请记住,回归结点的时候从这几行代码开始:
t.left(40) tree(branchLen-15,t) t.right(20) t.backward(branchLen)
如果你想很好地理解递归,你可以从这个程序开始。因为它很形象。
欢迎关注微信公众号:Python实用宝典