科赫曲线及其Python实现

一、科赫曲线

 1、简介

        科赫曲线(Koch Curve)是一种分形,其形态似雪花,故又称科赫雪花、雪花曲线。最早在1904年,由瑞典数学家海里格·冯·科赫(Niels Fabian Helge von Koch)在文章《于一条连续而无切线,可由初等几何构作的曲线》(法语原题:Sur une courbe continue sans tangente, obtenue par une construction géométrique élémentaire)中提出。

        科赫曲线作为典型的分形集,最大的特色是将自相似性首次引入数学的研究中,从而为芒德勃罗(B.B.Mandelbrot)在无序中建立有序,亦即分形几何的创立奠定了基础。这条著名的分形曲线是一系列复杂程度不断增加的褶皱曲线的极限,由于长度在有限区域中无限长,使得这条奇异曲线背离了几何形状的合理直觉。这一自相矛盾的事实曾给数学家们带来了不少困惑,直到分形几何理论赋予它深刻、丰富的内涵之后才迎刃而解。因此科赫曲线在分形几何的创立过程中有着重要的作用和影响。

三阶科赫雪花
三阶科赫雪花

2、特性

        科赫曲线拥有以下特性:

        (1)它是一条连续的回线,永远不会自我相交。

        (2)曲线处处不可导,是连续而无处可微的曲线。

        (3)曲线是无限长的,即在有限空间里的无限长度。

        (4)它是一个无限构造的有限表达,每次变化面积都会增加,但是总面积是有限的,不会超过初始三角形的外接圆。

        (5)它拥有自相似性,将它放大后会看到一个个小的科赫雪花。

3、构造

        科赫在文章中采用一个简单且具有非常明显的几何直观的方法来构造这一连续而无处可微的曲线。构造方法大体可以分为两步,第一步是:

        “用一条线段连接平面上的两个点 A和 B(见图1)。将线段 AB 划分为三个相等的部分 AC、CE 和 EB,设 CE 是等边三角形CDE 的底边,得到一条由 4 个相等线段组成的折线 ACDEB。为了确定这条曲线的走向,我们先规定一个正方向(例如从 A 到B)并将线段 AB 正方向的左边考虑为折线的正方向。为了简化注释,我们用运算 Ω表示从线段 AB 到折线 ACDEB 的渐变过程,折线 ACDEB 在线段 AB 正方向的左边,线段 AB 的正方向由 A 到 B 确定。”

        在第一步中,科赫给出了曲线构造的基本轮廓和思想,规定了曲线的正方向,同时建立了曲线构造的迭代递归模型。在模型建立后,他按照这个思想,从一条给定的线段开始,经过无限次迭代,得到一个无穷折线段序列,这个序列的极限即为科赫曲线。这也就是方法的第二步:

        “从一条给定的线段 AB 开始,设从 A到 B 是线段 AB 的正方向,用运算 Ω 表示折线 ACDEB 的构造过程,线段 AC、CD、DE、EB 均相等,它们的正方向分别是从 A到 C,C 到 D,D 到 E 和 E 到 B。将运算 Ω作用到上面的每一条线段,折线 ACDEB由折线 AFGHCIKLDMNOEPQRB 所取代,新折线包含 AF、FG 等 16 条相等的线段。在这些线段中再一次作用运算 Ω,将得到一条由个相等线段 AS、ST 等组成的折线ASTUF……。将 Ω 再作用到这些新的线段上,用同样的方式继续到无穷,可以得到一个无穷折线段序列,用 表示,它们分别由 ,条线段组成。其中 表示原始线段 AB, 表示折线 ACDEB,其他以此类推。可以看见当n 逐渐增大时, 将趋于一条在任何点处都没有切线的连续曲线。

        由于这条曲线的构造极其简单,而且具有很强的几何直观感,所以被科赫称为“朴素的直觉(Naive Intuition)”。科赫还从分析的角度给出了这条曲线连续但处处不可微的严格证明。对于连续性,他引入了分析中点集的概念,把曲线看成是无穷个点的集合,按照分析中连续性的定义,应用分析严格化过程中魏尔斯特拉斯所创立的“ε-δ”法则,证明了曲线弧上每一点都连续。对于处处不可微性,他将曲线上一点 K 在和不在某一折线 上分为两种情形,对于在某一折线 上的情形他又细分为点K在和不在某一折线 的顶点上两种情况,然后再按照切线的严格定义,通过割线逼近法和夹角判定法证明了曲线上任何一点都不可微。

4、影响

        科赫曲线一经诞生就引起了数学家巨大的兴趣,意大利数学家切萨罗不仅对科赫曲线大加赞赏,同时还第一次抽象出了自相似性这个分形几何中最重要的性质。他评论道:

       “这条曲线最使我注意之处是它的任何部分都相似于整体。如果想尽可能完全地想象它,必须意识到在这个结构中的每个小三角形均包含着以一个恰当比例缩小整体的形状。这个形状包含了每一个小三角形的缩小形式,后者又包含缩得更小的形状,按此循环以至无穷,……无论多么小的部分都能保持着自相似特征,这个特征使得这条曲线看上去非常奇妙。若是赋予它生命,那就必须把它全部除去才能摧毁它。否则,它将会从三角形深处重新不停地生长起来,如同宇宙自身的生命一样。”

       但任何事务都具有两面性,科赫曲线也不例外。它一方面解决了连续但处处不可微曲线的几何表达,另一方面人们一条直线经过数次重复弯折后演化出的复杂图形难以用直觉来理解,也加深了直觉的危机。

二、科赫曲线的Python实现

1、总体思路

        根据上文的分析,我们知道,科赫曲线有自相似性,因此,我们在绘图时只需要完成每一个小单元的绘制,然后将其无限迭代即可。

        从0阶曲线看出,此时图形为三角形,我们可以将图中三条边划分为三个基本的单元,我们称之为“边”。该部分图形即转变为“边”的三次重复问题。

        从大于0阶的曲线中可以看出,我们可以将每个“边”划分为四个基本单元,我们称之为“尖”。该部分图形即转变为“尖”的四次重复问题。

0阶科赫曲线  ​​​​​​

                       

1阶科赫曲线(红色为一个“尖”)

                                      

        问题分析完成后,我们开始选择语言。我们这里采用Python的turtle库来实现,turtle是Python标准库之一,是用于图像绘制的函数库。正如他的名字,在使用时会有有一个小海龟(窗口中为一个箭头),可以根据我们的指令在画布上爬动,爬动的轨迹即为我们绘制的图形。使用turtle库,我们不仅可以得到最终绘制的图形,还能看到图像绘制的全过程,也有助于我们理解图像的绘制过程。

2、代码实现

        代码实现上,我们只需要完成单个“尖”和“边”的绘制,然后采用图形自相似性递归实现图形的完整绘制。

        首先我们完成“尖”部分的代码。这里对于非0阶的每一个尖,根据上文的构造过程可知,size为每个“尖”的长度,中间部分向外画等边三角形,用turtle表示即为:

“走尖长 -> 转60度 -> 走尖长 -> 转-120度 -> 走尖长 -> 转60度 -> 走尖长”

        阶数部分采用递归实现,当非0阶时,对于每一尖进行下一阶的绘制,即在这条边上画n-1阶的尖,直到0阶时,绘制一条直线。代码实现为:

        然后我们完成“边”部分的代码。一个完整的科赫雪花由3个边组成,三条边首尾相连,边与边夹角120度。用turtle表示即为:

“画一条边 -> 转120度 -> 画一条边 -> 转120度 -> 画一条边”

        代码实现为:

        在主函数里,我们需要完成对turtle画布和画笔的一系列设置,同时调用边函数,开始绘制。代码实现及注释如下:

3、绘制效果

一阶科赫雪花曲线

 

三阶科赫雪花曲线
五阶科赫雪花曲线

  三、参考资料

  1. 江南,曲安京,李斐. 科赫曲线的产生和影响. 科学技术哲学研究2019,36: 100-105
  2. CSDN-htuhxf. Python笔记: 科赫雪花曲线(计算思维训练1).

附录:

        完整Python代码

import turtle


# 定义“尖”函数

def jian(size, n):# 两个参数 size为长度大小,n为阶数

    if n==0:#  0阶特判,为一条直线,长度即为size

        turtle.fd(size)

    else:# 高阶科赫雪花曲线,有尖存在

        for i in [0, 60, -120, 60]:

            # turtle在“尖”的四条线上改变的角度,分别为0°,60°,-120°,60°

            turtle.left(i) # 完成转弯操作

            jian(size/3, n-1) # 递归操作,完成每个边上的下一阶绘制


# 定义“边”函数

def bian(size, n):                   

    jian(size, n)# 绘制一条边

    turtle.right(120)# 转120度

    jian(size, n)

    turtle.right(120)

    jian(size, n)                     

    turtle.hideturtle()# 隐藏turtle绘图光标

    turtle.done()# 结束turtle绘图


# 定义主函数

def main(size, n):                    

    turtle.speed(0)                         

    # 设置速度,参数[0,10]:0为最大速度,其余[1,10]值越大、速度越快

    turtle.color('blue')# 设置颜色为蓝色

    turtle.pensize(2)# 设置画笔宽度为2

    turtle.setup(800,800, 100, 10)    

    # 设置画布,四个参数为:宽、高、坐标原点距左上角宽、高

    turtle.penup()# 抬起画笔,之后的画笔动作、就不会产生图线

    turtle.goto(-300, 100)# 将画笔移动到坐标(-300,100)处

    turtle.pendown()# 落下画笔,准备画图

    bian(size, n)# 开始调用边函数进行绘制


main(500, 10)# 调用主函数开始绘制

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_41626672

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值