引言
在编程的世界里,艺术与科学交汇,创造出令人惊叹的视觉作品。Python 的 turtle
模块就是一个极好的例子,它不仅让编程变得有趣,还能够激发创造力,将复杂的数学概念转化为直观的图形。本文将带你通过一个具体的项目——绘制一棵随风飘落叶子的树——来深入了解 turtle
模块的魔力。
Turtle 模块简介
Turtle 是 Python 的标准库模块之一,用于图形绘制和动画制作。它基于 Logo 编程语言的概念,使用一个“乌龟”(屏幕上的箭头)在屏幕上移动,并留下轨迹。通过控制这个“乌龟”的方向、位置和速度,我们可以轻松地绘制出各种图形和图案。
安装与环境
由于 turtle
是 Python 的内置模块,无需额外安装即可使用。只需确保你的 Python 环境已经安装好,就可以开始编程了。如果你使用的是 Jupyter Notebook 或其他不默认启用图形界面的环境,可能需要加上 %matplotlib inline
来确保图形可以正常显示。
代码解析
让我们深入分析这段代码,理解它是如何一步步构建出这棵美丽的树的。
from turtle import *
from random import *
from math import *
首先,我们导入了所需的模块:turtle
用于绘图,random
用于添加随机性,如叶子的飘落和树枝的角度,以及 math
用于计算和应用数学函数。
def tree(n, l):
...
接下来定义了一个名为 tree
的递归函数,该函数接收两个参数:n
表示递归的深度,即树的复杂程度;l
则是当前树枝的长度。
pd() # 下笔
t = cos(radians(heading() + 45)) / 8 + 0.25
pencolor(t, t, t)
pensize(n / 3)
forward(l) # 画树枝
函数开始时,下笔并设置画笔颜色和尺寸,然后向前绘制一段长度为 l
的树枝。
if n > 0:
b = random() * 15 + 10 # 右分支偏转角度
c = random() * 15 + 10 # 左分支偏转角度
d = l * (random() * 0.25 + 0.7) # 下一个分支的长度
right(b)
tree(n - 1, d)
left(b + c)
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)
circle(3)
left(90)
如果递归深度未达到极限,函数会生成左右两个分支,并递归调用自身。否则,它会在树枝的末端绘制一片叶子。
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)
circle(2)
left(90)
pu()
t = heading()
setheading(an)
backward(dis)
setheading(t)
这里我们增加了一些随机性,模拟树叶从树上飘落的情景。
bgcolor(0.5, 0.5, 0.5) # 背景色
ht() # 隐藏turtle
speed(0) # 速度 1-10渐进,0 最快
pu() # 抬笔
backward(100)
left(90) # 左转90度
pu() # 抬笔
backward(300) # 后退300
tree(12, 100) # 递归7层
done()
最后,设置了背景色,隐藏了乌龟图标,调整了速度,并调用了 tree
函数来开始绘制过程。
效果图
完整代码
from turtle import *
from random import *
from math import *
def tree(n, l):
pd() # 下笔
# 阴影效果
t = cos(radians(heading() + 45)) / 8 + 0.25
pencolor(t, t, t)
pensize(n / 3)
forward(l) # 画树枝
if n > 0:
b = random() * 15 + 10 # 右分支偏转角度
c = random() * 15 + 10 # 左分支偏转角度
d = l * (random() * 0.25 + 0.7) # 下一个分支的长度
# 右转一定角度,画右分支
right(b)
tree(n - 1, d)
# 左转一定角度,画左分支
left(b + c)
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)
circle(3)
left(90)
# 添加0.3倍的飘落叶子
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)
circle(2)
left(90)
pu()
# 返回
t = heading()
setheading(an)
backward(dis)
setheading(t)
pu()
backward(l) # 退回
bgcolor(0.5, 0.5, 0.5) # 背景色
ht() # 隐藏turtle
speed(0) # 速度 1-10渐进,0 最快
# tracer(0,0) # 这一行决定是否动态
pu() # 抬笔
backward(100)
left(90) # 左转90度
pu() # 抬笔
backward(300) # 后退300
tree(12, 100) # 递归7层
done()
结语
通过本文的学习,你不仅掌握了使用 turtle 模块的基本技巧,还学会了如何利用递归、随机性和数学函数来创造复杂的图形。这不仅是编程技能的提升,更是对自然界之美的艺术再现。希望这篇教程能激发你进一步探索编程与艺术结合的无限可能。