前言
分形几何是一个非常有意思的数学分支,和我们平时学的欧式几何不一样,分形图形拥有自相似性:把图形的局部放大之后,局部的形状和整体高度相似。科赫雪花,也叫科赫岛,是入门分形最经典的例子。
本次课程作业要求使用 Python,基于 turtle 海龟绘图库,实现可以指定阶数的科赫雪花,支持 0 阶到 4 阶的绘制。阶数越低图形越简单,阶数越高,雪花边缘的锯齿细节越多,曲线越细腻。通过这个实验,我们可以直观感受递归算法的魅力,理解递归的终止条件、递归调用、参数传递这些核心内容,同时熟悉 turtle 绘图库的基础 API。
很多初学递归的同学会觉得递归很难看懂,但是科赫雪花这个例子可视化效果很强,代码运行起来可以一步步看到画笔绘图的过程,很适合用来破除对递归的畏难心理。
需求说明
编写 Python 程序,绘制科赫雪花,要求:
- 支持输入阶数 n,n 的取值范围:0、1、2、3、4;
- 0 阶:等边三角形;
- 1~4 阶:按照科赫曲线分形规则迭代,阶数越高细节越丰富;
- 使用内置 turtle 库,无需额外 pip 安装第三方包;
- 代码结构分为两层:底层绘制单条科赫曲线,上层调用三次曲线拼成闭合雪花。
原理讲解
首先我们先搞懂科赫曲线的规则,科赫曲线是科赫雪花的基础:
- 递归终止条件:当阶数 level = 0 的时候,不再拆分,画笔直接向前画一条固定长度的直线;
- 如果阶数 level > 0:把当前线段平均分成三等份,舍弃中间那一段,替换成两条线段,形成一个凸起的等边三角形,转角依次是左转 60 度、右转 120 度、左转 60 度;
- 每一次递归调用的时候,线段长度都变成原来的 1/3,阶数减 1,持续拆分,直到降到 0 阶触发出口。
而科赫雪花,就是由三条科赫曲线首尾相连围成的闭合图形。画完一条科赫曲线之后,海龟向右转 120 度,连续画三次,刚好围成一个雪花轮廓。
这里简单介绍各阶形态:
- 0 阶:等边三角形,没有任何锯齿;
- 1 阶:三角形的三条边,每一条边都变成一个凸起;
- 2 阶:上一阶里面每一条小线段,再次拆分凸起,锯齿数量翻倍;
- 3 阶:典型的雪花样子,分形特征明显;
- 4 阶:锯齿非常密集,边缘接近平滑曲线,绘图耗时明显变长;
注意:阶数不要继续往上加,5 阶及以上计算量会爆炸,绘图速度极慢。
完整代码
import turtle def koch_curve(length, level): """ 绘制单条科赫曲线 :param length: 当前这条线段的总长度 :param level: 当前递归阶数 """ # 递归出口:阶数为0,直接画直线 if level == 0: turtle.forward(length) else: # 四段拆分:前进1/3,左转60,前进1/3,右转120,前进1/3,左转60,前进1/3 for angle in [0, 60, -120, 60]: turtle.left(angle) koch_curve(length / 3, level - 1) def koch_snowflake(length, level): """ 绘制完整科赫雪花,三条科赫曲线组成 :param length: 0阶三角形的边长 :param level: 雪花阶数 0~4 """ for _ in range(3): koch_curve(length, level) turtle.right(120) if __name__ == "__main__": # 画布基础设置 turtle.setup(width=700, height=700) turtle.speed(0) # 绘图速度,0为最快,数字1~10逐渐加快 turtle.pencolor("steelblue") turtle.pensize(1) # 抬笔移动位置,防止初始画线 turtle.penup() turtle.goto(-200, 100) turtle.pendown() # 修改第二个参数,切换0~4阶雪花 order = 3 print(f"正在绘制{order}阶科赫雪花,请稍等...") koch_snowflake(350, order) turtle.hideturtle() # 绘图完成后保持窗口,需要手动关闭 turtle.done()代码逐段解析
- 导入 turtle 库 turtle 是 Python 自带的海龟绘图库,专门用来做入门图形绘制,不需要额外安装。
- koch_curve 函数(核心递归函数) 这是整个程序的重点。level=0 就是递归的出口,避免无限递归。当阶数大于 0 时,循环 4 次递归调用,每次线段长度除以 3,阶数减一,配合角度转向,完成一段科赫折线。
- koch_snowflake 雪花组装函数 循环三次调用科赫曲线,每次画完一条曲线右转 120°,三条拼接闭合,形成雪花。
- 画布配置部分 setup 设置窗口大小,speed (0) 关闭动画延迟,加速绘图;penup/goto 用来移动画笔到合适位置,避免一开始拖动出多余线条;pencolor 可以自定义画笔颜色。
不同阶数效果说明
- order=0:等边三角形,没有分形凸起,是雪花最基础的原型;
- order=1:三条边各出现一个尖角,能看出基础变形;
- order=2:尖角上继续长出更小的尖角,分形特征开始明显;
- order=3:大众印象里标准的科赫雪花,锯齿均匀美观;
- order=4:细节拉满,锯齿非常多,绘制时间会明显增加,耐心等待画布渲染。
知识点总结
- 递归算法:函数调用自身,设置明确终止条件,层层分解问题;
- 分形与自相似:局部结构和整体结构保持一致,是分形最核心的特点;
- turtle 库常用 API:forward 前进、left/right 转向、penup 抬笔、pendown 落笔、goto 坐标移动;
- 角度几何:利用等边三角形内角 60°、外角 120°,控制画笔转向;
- 算法复杂度:阶数每升高一级,绘图的线段数量会快速增长,属于指数级增长。
调试踩坑记录
问题 1:图形画出来对不上,形状错乱 原因:转向角度写错,60、-120、60 这个序列不能随便改动,角度错了整个分形就变形。
问题 2:递归无限循环,程序卡死 原因:忘记写 level==0 的递归出口,函数会无限调用自己,直接栈溢出。
问题 3:雪花超出画布看不见 解决:调整 goto 的坐标,或者缩短初始 length 边长,把图形往画布中间放。
拓展方向
我们还可以继续丰富这个项目:
- 写循环,一次性在画布上画出 0 到 4 阶 5 个雪花并排对比;
- 增加填充颜色,给雪花上色;
- 增加键盘输入交互,运行时手动输入想要绘制的阶数;
- 改造为科赫曲线动画,放慢绘图速度,观察递归绘制顺序。