跳到主要内容使用 Python 绘制树木的几种方法 | 极客日志Python大前端算法
使用 Python 绘制树木的几种方法
综述由AI生成利用 Python 的 turtle 图形库和分形算法,可以绘制出多种风格的树木图像。文章包含樱花树、绿叶树、落叶树及基于 L 系统生成的芦苇风树等四个示例,通过递归函数和随机数控制树枝生长与花瓣飘落效果,展示了编程绘图的数学之美与实现细节。内容涵盖代码结构解析、关键函数说明及运行环境要求,适合对图形编程感兴趣的开发者参考。
ApiHolic21 浏览 使用 Python 绘制树木的几种方法
古人有诗云'庭中有奇树,绿叶发华滋',树之美,或婀娜、或繁茂、或苍劲、或青翠。Python 的 turtle 库提供了强大的绘图功能,结合递归算法和随机数,可以生动地模拟出不同季节和风格的树木。
1. 樱花树:递归与色彩变化
本示例通过递归函数 Tree 模拟樱花树的生长过程。树干颜色根据分支长度动态变化,末端花瓣飘落效果增加了画面的动感。
import turtle as T
import random
import time
def Tree(branch, t):
time.sleep(0.0005)
if branch > 3:
if 8 <= branch <= 12:
if random.randint(0, 2) == 0:
t.color('snow')
else:
t.color('lightcoral')
t.pensize(branch / 3)
elif branch < 8:
if random.randint(0, 1) == 0:
t.color('snow')
else:
t.color('lightcoral')
t.pensize(branch / 2)
else:
t.color('sienna')
t.pensize(branch / 10)
t.forward(branch)
a = 1.5 * random.random()
t.right( * a)
b = * random.random()
Tree(branch - * b, t)
t.left( * a)
Tree(branch - * b, t)
t.right( * a)
t.up()
t.backward(branch)
t.down()
():
i (m):
a = - * random.random()
b = - * random.random()
t.up()
t.forward(b)
t.left()
t.forward(a)
t.down()
t.color()
t.circle()
t.up()
t.backward(a)
t.right()
t.backward(b)
t = T.Turtle()
w = T.Screen()
t.hideturtle()
t.getscreen().tracer(, )
w.screensize(bg=)
t.left()
t.up()
t.backward()
t.down()
t.color()
Tree(, t)
Petal(, t)
w.exitonclick()
20
1.5
10
40
10
20
def
Petal
m, t
for
in
range
200
400
10
20
90
'lightcoral'
1
90
5
0
'white'
90
150
'sienna'
60
200
- 递归逻辑:
Tree 函数不断调用自身,每次调用减少分支长度 (branch - 10 * b),直到小于 3 时停止,形成树的分叉结构。
- 随机性:使用
random 模块控制分支角度和长度,使每棵树形态各异。
- 画笔设置:根据分支粗细调整
pensize,模拟真实树木的根部粗、梢部细的特征。
2. 绿叶树:面向对象与阴影效果
此示例采用面向对象的方式封装树类,利用三角函数计算阴影效果,使树叶呈现立体感。
from turtle import *
from random import *
from math import *
class Tree:
def __init__(self):
setup(1000, 500)
bgcolor(1, 1, 1)
speed(10)
tracer(0, 0)
pu()
backward(100)
left(90)
backward(300)
def tree(self, n, l):
pd()
t = cos(radians(heading() + 45)) / 8 + 0.25
pencolor(t, t, t)
pensize(n / 1.2)
forward(l)
if n > 0:
b = random() * 15 + 10
c = random() * 15 + 10
d = l * (random() * 0.25 + 0.7)
right(b)
self.tree(n - 1, d)
left(b + c)
self.tree(n - 1, d)
right(c)
else:
right(90)
n = cos(radians(heading() - 45)) / 4 + 0.5
pencolor(n, n * 0.8, n * 0.8)
fillcolor(n, n * 0.8, n * 0.8)
begin_fill()
circle(3)
left(90)
end_fill()
if random() > 0.7:
pu()
t = heading()
an = -40 + random() * 40
setheading(an)
dis = int(800 * random() * 0.5 + 400 * random() * 0.3 + 200 * random() * 0.2)
forward(dis)
setheading(t)
pd()
right(90)
n = cos(radians(heading() - 45)) / 4 + 0.5
pencolor(n * 0.5 + 0.5, 0.4 + n * 0.4, 0.4 + n * 0.4)
fillcolor(n, n * 0.8, n * 0.8)
begin_fill()
circle(2)
left(90)
end_fill()
pu()
t = heading()
setheading(an)
backward(dis)
setheading(t)
def main():
tree = Tree()
tree.tree(12, 100)
done()
if __name__ == '__main__':
main()
- 类封装:将绘图环境初始化和树形生成逻辑封装在
Tree 类中,便于管理状态。
- 数学计算:利用
cos 和 radians 计算颜色深浅,模拟光照下的阴影效果。
- 叶子绘制:当递归深度为 0 时,绘制圆形代表叶子,并随机决定是否生成落叶效果。
3. 落叶树:花瓣位置生成
本示例重点展示花瓣(叶子)在特定坐标区域的分布,模拟风吹花落的情景。
from turtle import *
from random import *
def drawTree(n, l):
pendown()
pencolor('#5d3c3c')
pensize(n / 1.5)
forward(l)
if n > 0:
dr = randint(30, 40)
dl = randint(30, 40)
move = l * (random() * 0.4 + 0.5)
right(dr)
drawTree(n - 1, move)
left(dr + dl)
drawTree(n - 1, move)
right(dl)
else:
drawPetal(3)
penup()
backward(l)
def petalPlace(m, x, y):
penup()
goto(x, y)
pendown()
setheading(0)
tracer(False)
for i in range(m):
if i == 0:
drawPetal(5)
else:
penup()
goto(x, y)
a = randint(20, 400)
b = randint(-50, 50)
forward(a)
left(90)
forward(b)
right(90)
pendown()
drawPetal(5)
def drawPetal(n):
colormode(255)
r = randint(200, 255)
g = randint(8, 158)
b = randint(8, 158)
begin_fill()
fillcolor(r, g, b)
pencolor(r, g, b)
circle(n)
end_fill()
def run():
setup(1.0, 1.0)
penup()
goto(-50, -150)
left(90)
pendown()
hideturtle()
tracer(False)
drawTree(13, 150)
petalPlace(160, -100, -150)
run()
done()
if __name__ == '__main__':
run()
- 坐标定位:
petalPlace 函数允许在指定坐标 (x, y) 处生成花瓣,增加了布局的灵活性。
- 颜色随机:RGB 值随机生成,确保每一片花瓣颜色略有不同。
4. L-系统:分形芦苇风树
L-系统(Lindenmayer System)是一种形式文法,常用于模拟植物生长。本例通过重写规则生成复杂的分形结构。
import turtle
import random
stack = []
def createWord(max_it, word, proc_rules, x, y, turn):
turtle.up()
turtle.home()
turtle.goto(x, y)
turtle.right(turn)
turtle.down()
t = 0
while t < max_it:
word = rewrite(word, proc_rules)
drawit(word, 5, 20)
t = t + 1
def rewrite(word, proc_rules):
wordList = list(word)
for i in range(len(wordList)):
curChar = wordList[i]
if curChar in proc_rules:
wordList[i] = proc_rules[curChar]
return "".join(wordList)
def drawit(newWord, d, angle):
newWordLs = list(newWord)
for i in range(len(newWordLs)):
cur_Char = newWordLs[i]
if cur_Char == 'F':
turtle.forward(d)
elif cur_Char == '+':
turtle.right(angle)
elif cur_Char == '-':
turtle.left(angle)
elif cur_Char == '[':
state_push()
elif cur_Char == ']':
state_pop()
def state_push():
global stack
stack.append((turtle.position(), turtle.heading()))
def state_pop():
global stack
position, heading = stack.pop()
turtle.up()
turtle.goto(position)
turtle.setheading(heading)
turtle.down()
def randomStart():
x = random.randint(-300, 300)
y = random.randint(-320, -280)
heading = random.randint(-100, -80)
return ((x, y), heading)
def main():
rule_sets = []
rule_sets.append(((3, 5), 'F', {'F': 'F[+F][-F]F'}))
rule_sets.append(((4, 6), 'B', {'B': 'F[-B][+ B]', 'F': 'FF'}))
rule_sets.append(((2, 4), 'F', {'F': 'FF+[+F-F-F]-[-F+F+F]'}))
tree_count = 50
turtle.tracer(10, 0)
for x in range(tree_count):
rand_i = random.randint(0, len(rule_sets) - 1)
selected_ruleset = rule_sets[rand_i]
i_range, word, rule = selected_ruleset
low, high = i_range
i = random.randint(low, high)
start_position, start_heading = randomStart()
start_x, start_y = start_position
createWord(i, word, rule, start_x, start_y, start_heading)
if __name__ == '__main__':
main()
- 重写规则:
rewrite 函数根据预定义的规则集替换字符,例如 F 替换为 F[+F][-F]F,实现分形迭代。
- 状态栈:使用
stack 保存画笔位置和方向,支持 [ 和 ] 符号进行分支回溯。
- 批量生成:循环生成多棵树木,展示不同规则下的形态差异。
总结
以上四个示例展示了从基础递归到复杂分形算法的多种树木绘制方案。运行这些代码需要安装 Python 环境并导入标准库 turtle 和 random。通过调整参数如分支长度、角度范围和颜色阈值,你可以创造出独一无二的数字艺术作品。建议尝试修改代码中的随机种子或规则集,探索更多可能性。
相关免费在线工具
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- Gemini 图片去水印
基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online
- curl 转代码
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
- Markdown转HTML
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online