分形通常被定义为“一个粗糙或零碎的几何形状,可以分成数个部分,且每一部分都(至少近似地)是整体缩小后的形状”。分形树则顾名思义——亦即理论上无论放大多少倍,都具有相同形状。
(以下图形均由turtle库绘制)
因为分形树每个部分都具有相同形状,因而我们可以从最基本的情况开始考虑,亦即当树只有一层分枝时。可以定义一个函数tree_1(),用turtle画出一层分枝的树并回到树根处。于是可以很显然的想到两层分枝时的绘制,可以定义一个函数tree_2(),在第一次的分枝末段调用tree_1()来画出第二层分枝。同理可以定义tree_3(),同时在第一次分枝末段调用tree_2()来画出第二、三层分枝。于是每画到倒数第n层树枝末段时,调用函数tree_n-1(),直到n = 1。由此易知定义tree(n),通过递归实现分形树的绘制。
import turtle
t = turtle
tree_1()、tree_2()、tree_3()
def tree_1(lent=15):
"""绘制一层分枝分形树"""
t.forward(lent + 20) # 树干比树枝长20
t.right(30)
t.forward(lent)
t.backward(lent)
t.left(60)
t.forward(lent)
t.backward(lent)
t.right(30)
t.backward(lent + 20) # 回到树根处
def tree_2(lent=55):
"""绘制两层分枝分形树"""
t.forward(lent + 20)
t.right(30)
tree_1() # 末段调用一层分形树的绘制
t.left(60)
tree_1() # 再次调用
t.right(30)
t.backward(lent + 20) # 回到树根处
def tree_3(lent=75):
"""绘制三层分枝分形树"""
t.forward(lent + 20)
t.right(30)
tree_2() # 末段调用两层分形树的绘制
t.left(60)
tree_2() # 再次调用
t.right(30)
t.backward(lent + 20) # 回到树根处
tree()
def tree(lent):
"""递归绘制分形树"""
if lent == 15: # 直到下一层为一层分枝分形树
t.forward(lent + 20)
t.right(30)
t.forward(lent)
t.backward(lent)
t.left(60)
t.forward(lent)
t.backward(lent)
t.right(30)
t.backward(lent + 20)
else:
t.forward(lent + 20)
t.right(30)
tree(lent) # 调用倒数下一层树的绘制
t.left(60)
tree(lent) # 再次调用
t.right(30)
t.backward(lent + 20)
然而对于上述tree()函数,最顶层分枝实际上并没有画出下一层分枝(理论上有),再注意到,当tree(lent)不被调用时,该层分枝满足else下的方法,于是可以对tree()函数进行优化,同时将角度ang,主树干长度,树枝树干长度差均设为参数。
def tree(lent, ang=30, dif=20):
"""递归绘制分形树"""
if lent > 0:
t.forward(lent)
t.right(ang)
tree(lent - dif)
t.left(2 * ang)
tree(lent - dif)
t.right(ang)
t.backward(lent)
else:
print("done")
四、完整程序
import turtle
import random
t = turtle
t.color('brown')
t.left(90)
t.penup()
t.goto(0, -300)
t.pendown()
t.speed(999)
def tree(lent, dif=15):
"""递归绘制分形树"""
ang = random.randint(18, 36) # 随机角度使树更加真实
if lent > 0:
t.width(lent//10)
t.forward(lent)
t.right(ang)
tree(lent - dif)
t.left(2 * ang)
tree(lent - dif + 8)
if lent - dif <= 0:
t.color('pink')
t.dot(20)
t.color('brown')
t.right(ang)
t.backward(lent)
else:
pass
tree(120)
t.done()
五、运行结果
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)