1. 前言分形几何是几何数学中的一个分支,也称大自然几何学,由著名数学家本华曼德勃罗( 法语:BenoitB.Mandelbrot)在 1975 年构思和发展出来的一种新的几何学。 分形几何是对大自然中 微观与宏观 和谐统一之美的发现,分形几何最大的特点:
![]() 什么是分形算法?所谓 分形算法 就是使用计算机程序模拟出大自然界的分形几何图案,是 分形几何数学 与 计算机科学 相融合的艺术。 由于分形图形相似性的特点,分形算法多采用递归实现。 2. 分形算法2.1 科赫雪花科赫雪花是由瑞典数学家科赫在 1904 年提出的一种不规则几何图形,也称为雪花曲线。 ![]() 分形图形的特点是 整体几何图形 是由一个 微图形结构 自我复制、反复叠加形成,且最终形成的整体图案和微图形结构一样。在编写分形算法时,需要先理解微图案的生成过程。 ![]() 科赫雪花的微图案生成过程:
科赫微图形算法实现:使用 Python 自带小海龟模块绘制,科赫雪花递归算法的出口的是画直线。 import turtle'''size:直线的长度level: 科赫雪花的层次'''def koch(size, level): if n == 1: turtle.fd(size) else: for i in [0, 60, -120, 60]: turtle.left(i) # 旋转后,再绘制 koch(size // 3, level - 1) 参数说明:
0 阶和 1 阶 科赫雪花递归流程:
![]() 2 阶科赫雪花:![]() 可以多画几个科赫雪花,布满整个圆周。 import turtleturtle.speed(100)def ke_line(line_, n): if n == 0: turtle.fd(line_) else: line_len = line_ // 3 for i in [0, 60, -120, 60]: turtle.left(i) ke_line(line_len, n - 1)# 原始线长度line = 300# 移动小海龟画布左下角turtle.penup()turtle.goto(-150, -150)turtle.pendown()# 几阶科赫雪花di_gui_deep = int(input('请输入科赫雪花的阶数:'))while True: # 当多少科赫雪花围绕成一个圆周时,就构成一个完整的雪花造型 count = int(input('需要几个科赫雪花:')) if 360 % count != 0: print('请输入 360 的倍数') else: breakfor i in range(count): ke_line(line, di_gui_deep) turtle.left(360 // count)turtle.done() 4 个 3 阶科赫雪花:每画完一个后旋转 90 度,然后再绘制另一个。 ![]() 6 个 3 阶科赫雪花:每画完一个后,旋转 60 度再画另一个。 ![]() 科赫雪花的绘制并不难,本质就是画直线、旋转、再画直线…… 2.2 康托三分集由德国数学家 格奥尔格·康托尔 在1883年引入,是位于一条线段上的一些点的集合。最常见的构造是 康托尔三分点集 ,由去掉一条线段的中间三分之一得出。 构造过程:
![]() 编码实现:使用递归实现。
![]() 康托三分集的递归算法很直观。 2.3 谢尔宾斯基三角形谢尔宾斯基三角形(英语:Sierpinski triangle)由波兰数学家谢尔宾斯基在1915年提出。 构造过程:
编码实现:谢尔宾斯基三角形就是不停的画三角形,在编码之前约定三角形点之间的关系以及绘制方向如下图所示。 ![]() import turtleimport mathturtle.speed(100)''' 通过连接 3 个点的方式绘制三角形 pos是元组的元组((x1,y1),(x2,y2),(x3,y3))'''def draw_triangle(pos): turtle.penup() # 移到第一个点 turtle.goto(pos[0]) turtle.pendown() # 连接 3 个点 for i in [1, 2, 0]: turtle.goto(pos[i]) # 计算三角形任意两边的中点坐标def get_mid(p1, p2): return (p1[0] + p2[0]) / 2, (p1[1] + p2[1]) / 2'''绘制 谢尔宾斯基三角形'''def sierpinski_triangle(*pos): # 用给定的点绘制三角形 draw_triangle(pos) p1, p2, p3 = pos # 计算三角形的边长 side = math.fabs((p3[0] - p1[0]) / 2) # 如果边长满足条件,继续绘制其它三角形 if side > 10: # p1和p2线段 的中心点 p1_p2_center_x, p1_p2_center_y = get_mid(p1, p2) # p2和p3线段 的中心点 p2_p3_center_x, p2_p3_center_y = get_mid(p2, p3) # p1和p3线段 的中心点 p1_p3_center_x, p1_p3_center_y = get_mid(p1, p3) # 绘制左下角三角形 sierpinski_triangle(p1, (p1_p2_center_x, p1_p2_center_y), (p1_p3_center_x, p1_p3_center_y)) # 绘制上边三角形 sierpinski_triangle((p1_p2_center_x, p1_p2_center_y), p2, (p2_p3_center_x, p2_p3_center_y)) # 绘制右下角三角形 sierpinski_triangle((p1_p3_center_x, p1_p3_center_y), (p2_p3_center_x, p2_p3_center_y), p3)# 第一个点指左边点,第二点指上面的点,第三个指右边的点。sierpinski_triangle((-200, -100), (0, 200), (200, -100))turtle.done() 代码执行之后的结果: ![]() 用随机的方法(Chaos Game),绘制谢尔宾斯基三角形:构造过程:
![]()
![]()
![]()
![]()
注意,是画点,上面的线段是为了直观理解中心点位置。 编码实现:
随机法是一个神奇的存在,当点数量很少时,看不出到底在画什么。当点的数量增加后,如成千上万后,会看到谢尔宾斯基三角形跃然于画布上,不得不佩服数学家们天才般的大脑。 下图是点数量为 10000 时的谢尔宾斯基三角形,是不是很震撼。 ![]() 2.4 分形树绘制分形树对于递归调用过程的理解有很大的帮助,其实前面所聊到的递归算法都是树形递进。分形树能很形象的描述树形递归的过程。 ![]() 分形树的算法实现:import turtledef draw_tree(size): if size >= 20: turtle.forward(size) # 1 # 画右边树 turtle.right(20) draw_tree(size - 40) # 2 # 画左边树 turtle.left(40) draw_tree(size - 40) # 后退 turtle.right(20) turtle.backward(size)turtle.left(90)draw_tree(80)turtle.done() 为了理解分形树的递归过程,如上代码可以先仅画一个树干两个树丫。 ![]() 下面以图示方式显示左右两边的树丫绘制过程。 ![]() 3. 总结分形几何是大自然对数学的馈赠,当然这离不开数学家们的发现与研究,通过计算机科学对分形几何的模拟,可以以可视化的方式更直观地研究分形几何学。这也是计算机科学对于各学科的巨大贡献。 |
|