我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Python 分形算法代码详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Python 分形算法代码详解

1. 前言

分形几何是几何数学中的一个分支,也称大自然几何学,由著名数学家本华曼德勃罗( 法语:BenoitB.Mandelbrot)在 1975 年构思和发展出来的一种新的几何学。

分形几何是对大自然中微观与宏观和谐统一之美的发现,分形几何最大的特点:

  • 整体与局部的相似性: 一个完整的图形是由诸多相似的微图形组成,而整体图形又是微图形的放大。

局部是整体的缩影,整体是局部的放大。

  • 具有自我叠加性: 整体图形是由微图形不断重复叠加构成,且具有无限叠加能力。

什么是分形算法?

所谓分形算法就是使用计算机程序模拟出大自然界的分形几何图案,是分形几何数学与计算机科学相融合的艺术。

由于分形图形相似性的特点,分形算法多采用递归实现。

2. 分形算法

2.1 科赫雪花

科赫雪花是由瑞典数学家科赫在 1904 年提出的一种不规则几何图形,也称为雪花曲线。

分形图形的特点是整体几何图形是由一个微图形结构自我复制、反复叠加形成,且最终形成的整体图案和微图形结构一样。在编写分形算法时,需要先理解微图案的生成过程。

科赫雪花的微图案生成过程:

  • 先画一条直线。科赫雪花本质就由一条直线演化而成。
  • 三等分画好的直线。
  • 取中间线段,然后用夹角为 60° 的两条等长线段替代。
  • 可在每一条线段上都采用如上方式进行迭代操作,便会构造出多层次的科赫雪花。

科赫微图形算法实现:

使用 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)

参数说明:

  • size: 要绘制的直线长度。
  • level: 科赫雪花的层次。

0 阶和 1 阶 科赫雪花递归流程:

import turtle
turtle.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()
# 1 阶科赫雪花
di_gui_deep = 1
ke_line(line, di_gui_deep)
turtle.done()

2 阶科赫雪花:

可以多画几个科赫雪花,布满整个圆周。

import turtle
turtle.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:
        break
for 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年引入,是位于一条线段上的一些点的集合。最常见的构造是康托尔三分点集,由去掉一条线段的中间三分之一得出。

构造过程:

  • 绘制一条给定长度的直线段,将它三等分,去掉中间一段,留下两段。
  • 再将剩下的两段再分别三等分,同样各去掉中间一段,剩下更短的四段……
  • 将这样的操作一直继续下去,直至无穷,由于在不断分割舍弃过程中,所形成的线段数目越来越多,长度越来越小,在极限的情况下,得到一个离散的点集,称为康托尔点集。

编码实现: 使用递归实现。

import turtle
''''
(sx,sy)线段的开始位置
(ex,ey)线段的结束位置
'''
turtle.speed(100)
turtle.pensize(2)
def draw_kt(sx, sy, ex, ey):
    turtle.penup()
    # 小海龟移动开始位置
    turtle.goto(sx, sy)
    turtle.pendown()
    # # 小海龟移动结束位置
    turtle.goto(ex, ey)
    # 起始点与结束点之间的距离
    length = ex - sx
    # 如果直线长线大于 5 则继续画下去
    if length > 5:
        # 左边线段的开始 x 坐标
        left_sx = sx
        # y 坐标向下移动 30
        left_sy = sy - 50
        # 左边线段的结束坐标
        left_ex = sx + length / 3
        left_ey = left_sy
        # 右边线段的开始坐标
        right_sx = ex - length / 3
        right_sy = ey - 50
        # 右边线段的结束坐标
        right_ex = ex
        right_ey = right_sy
        draw_kt(left_sx, left_sy, left_ex, left_ey)
        draw_kt(right_sx, right_sy, right_ex, right_ey)
draw_kt(-300, 200, 300, 200)
turtle.done()

康托三分集的递归算法很直观。

2.3 谢尔宾斯基三角形

谢尔宾斯基三角形(英语:Sierpinski triangle)由波兰数学家谢尔宾斯基在1915年提出。

构造过程:

  • 取一个实心的三角形(最好是等边三角形)。
  • 沿三边中点的连线,将它分成四个小三角形。
  • 去掉中间的那一个小三角形。
  • 对其余三个小三角形重复上述过程直到条件不成立。

编码实现: 谢尔宾斯基三角形就是不停的画三角形,在编码之前约定三角形点之间的关系以及绘制方向如下图所示。

import turtle
import math
turtle.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),绘制谢尔宾斯基三角形:

构造过程:

任意取平面上三点 A,B,C,组成一个三角形。

在三角形 ABC 内任意取一点 P,并画出该点。

找出 P 和三角形其中一个顶点的中点,并画出来。

把刚才找出来的中心点和三角形的任一顶点相连接,同样取其中点,并画出来。

重复上述流程,不停的获取中心点。

注意,是画点,上面的线段是为了直观理解中心点位置。

编码实现:

import turtle
import random
turtle.speed(100)
turtle.bgcolor('black')
colors = ['red', 'green', 'blue', 'orange', 'yellow']
# 画等边三角形
def draw_triangle(pos):
    turtle.penup()
    turtle.goto(pos[0])
    turtle.pendown()
    for i in [1, 2, 0]:
        turtle.goto(pos[i])

def sierpinski_triangle(*pos):
    # 画三角形
    draw_triangle(pos)
    p1, p2, p3 = pos
    # 在三角形中任取一点
    ran_x, ran_y = (p1[0] + p3[0]) / 2, (p2[1] + p3[1]) / 2
    for i in range(10000):
        # 画点
        turtle.penup()
        turtle.goto(ran_x, ran_y)
        turtle.pendown()
        turtle.dot(3, colors[i % 5])
        # 随机选择 3 个顶点的一个顶点
        ran_i = random.randint(0, 2)
        ding_p = pos[ran_i]
        # 计算任意点和顶点的中心点
        ran_x, ran_y = (ran_x + ding_p[0]) / 2, (ran_y + ding_p[1]) / 2
sierpinski_triangle((-200, -100), (0, 200), (200, -100))
turtle.done()

随机法是一个神奇的存在,当点数量很少时,看不出到底在画什么。当点的数量增加后,如成千上万后,会看到谢尔宾斯基三角形跃然于画布上,不得不佩服数学家们天才般的大脑。

下图是点数量为 10000 时的谢尔宾斯基三角形,是不是很震撼。

2.4 分形树

绘制分形树对于递归调用过程的理解有很大的帮助,其实前面所聊到的递归算法都是树形递进。分形树能很形象的描述树形递归的过程。

分形树的算法实现:

import turtle
def 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. 总结

分形几何是大自然对数学的馈赠,当然这离不开数学家们的发现与研究,通过计算机科学对分形几何的模拟,可以以可视化的方式更直观地研究分形几何学。这也是计算机科学对于各学科的巨大贡献。

到此这篇关于Python 分形算法代码详解的文章就介绍到这了,更多相关Python 分形算法内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Python 分形算法代码详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Python实现调度算法代码详解

调度算法 操作系统管理了系统的有限资源,当有多个进程(或多个进程发出的请求)要使用这些资源时,因为资源的有限性,必须按照一定的原则选择进程(请求)来占用资源。这就是调度。目的是控制资源使用者的数量,选取资源使用者许可占用资源或占用资源。 在
2022-06-04

Python自然语言处理之词干,词形与最大匹配算法代码详解

本文主要对词干提取及词形还原以及最大匹配算法进行了介绍和代码示例,Python实现,下面我们一起看看具体内容。 自然语言处理中一个很重要的操作就是所谓的stemming和lemmatization,二者非常类似。它们是词形规范化的两类重要方
2022-06-04

t-SNE算法的原理和Python代码实现详解

T分布随机邻域嵌入(t-SNE),是一种用于可视化的无监督机器学习算法,使用非线性降维技术,根据数据点与特征的相似性,试图最小化高维和低维空间中这些条件概率(或相似性)之间的差异,以在低维空间中完美表示数据点。因此,t-SNE擅长在二维或三
t-SNE算法的原理和Python代码实现详解
2024-01-23

python二分查找算法代码怎么写

下面是一个示例的Python二分查找算法代码:def binary_search(arr, target):left = 0right = len(arr) - 1while left 此代码中的binary_search函数接受一个已
2023-10-22

Java方法递归的形式和常见递归算法代码分析

本篇内容介绍了“Java方法递归的形式和常见递归算法代码分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!方法递归方法递归的形式什么是方法递
2023-07-05

Python 图形绘制详细代码怎么写

这篇文章给大家介绍Python 图形绘制详细代码怎么写,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1、条形图下面介绍条形图的画法。1.1 代码import matplotlib.pyplot as plt# x-co
2023-06-22

Python三目运算符(三元运算符)用法详解(含实例代码)

三元运算符在Python里被称为条件表达式,这些表达式基于真(true)/假(false)的条件判断,在Python2.4以上才有了三元操作,下面这篇文章主要给大家介绍了关于Python三目运算符(三元运算符)用法的相关资料,需要的朋友可以参考下
2023-02-03

python二分查找算法的代码怎么写

以下是一个简单的二分查找算法的Python代码实现:def binary_search(arr, target):left = 0right = len(arr) - 1while left 使用该算法时,需要传入一个有序的数组 `ar
2023-10-26

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录