混沌与分形(一):谢尔宾斯基三角形与门格海绵

article/2025/1/7 7:04:33

研究混沌运动,少不了对分形理论的探讨。分形:通常被定义为“一个粗糙或零碎的几何形状,可以分成数个部分,且每一部分都(至少近似地)是整体缩小后的形状”,即具有自相似的性质。

本篇将从一维过度到三维介绍分形图案的产生,一维类比康托尔集直线三等分的生成,此处比较简单我们不过多讨论,我们重点分析如何通过使用Java语言,实现Sierpinski和Menger sponge分形图案的过程(多图)。

谢尔宾斯基(Sierpinski)三角形

谢尔宾斯基三角形和它本身的一部分完全相似,它是自相似集的经典例子。

构造特点

  1. 取一个三角形边框(常用等边三角形)
  2. 沿三边中点的连线,将它分成四个小三角形
  3. 去掉中间的那一个小三角形
  4. 对其余三个小三角形都重复1~3的操作

代码实现

UI界面鼠标监听器获取鼠标点击处的坐标,再由此坐标和等腰三角的边长关系,得到三角形其余两点坐标:

int x = (int)e.getX();
int y = (int)e.getY();
int length = 120;//设定三角形边长为2*length
int x2 = x+length;//以下为坐标变换
int x3 = x-length;
int y2 = (int)(y-length*Math.sqrt(3));
int y3 = (int)(y-length*Math.sqrt(3));
int count =6;//迭代次数初始值

方法一:

此方法是绘制Sierpinski三角形的典型思路,与构造特点思路对应。

public void triangle_1(int x1,int y1,int x2,int y2,int x3,int y3,int count){//将三角形三顶点坐标存入数组中int m[]={x1,x2,x3};int n[]={y1,y2,y3};//绘制三角形边框g.drawPolygon(m, n, 3);//迭代次数减1,再判断count--;if(count>0){//计算三边中点坐标int x4=(x1+x2)/2;int x5=(x1+x3)/2;int x6=(x2+x3)/2;int y4=(y1+y2)/2;int y5=(y1+y3)/2;int y6=(y2+y3)/2;//迭代到不包括最中间的其余三个小三角形中triangle_1(x1,y1,x4,y4,x5,y5,count);triangle_1(x2,y2,x4,y4,x6,y6,count);triangle_1(x3,y3,x5,y5,x6,y6,count);}}

绘制结果(1)


此结果是迭代6次的效果,三顶点变换方向不同,效果会有区别,但大同小异。

方法二:

与方法一的思路略有不同,我们不排除中间的三角形,而是以它为主,先绘制最中间的实心三角形,再对三边的三个不同方向作迭代,变化过程中只改变三角形边长大小为之前的1/2,并朝此方向作平移,重复上述过程。

public void triangle_2(int length,int x1,int y1,int x2,int y2,int x3,int y3,int l){/*此处代码作用是将三角形三顶点坐标转换,并保存至数组中由于与上述重复,不再赘述*///判断断边长大小决定是否继续递归if(length>4){g.setColor(new Color(length,l/4,length+l/4));g.fillPolygon(m, n, 3);length = length/2;//边长递减一半l = (int) (2*length*Math.sqrt(3));   //小三角形每次变化所要平移的距离System.out.println("X坐标:"+m[0]+"-"+m[1]+"-"+m[2]+" Y坐标:"+n[0]+"-"+n[1]+"-"+n[2]+" 边长="+2*length);g.setColor(new Color(l/4,l/4+length,l/4));g.fillPolygon(m, n, 3);//迭代到不包括最中间的其余三个小三角形中triangle_2(length,x1,y1,x2,y2,x3,y3,l);triangle_2(length,x1+2*length,y1+l,x2+2*length,y2+l,x3+2*length,y3+l,l);triangle_2(length,x1-2*length,y1+l,x2-2*length,y2+l,x3-2*length,y3+l,l);}}

绘制结果(2)

在这里插入图片描述
迭代过程中对三角形的填充的颜色做了变化,如果变换背景颜色,与最后迭代时小三角形颜色相近,会产生更好的效果:
在这里插入图片描述
同理,Sierpinski矩形地毯的绘制思路与Sierpinski三角形完全一致,不再赘述,只是我们可以多些变化,比如添加倒角效果如下:
在这里插入图片描述
可能渐变效果并不好,此处只是分享一种变化的思路,Sierpinski的部分我们就介绍到这里。

门格海绵(Menger sponge)

它是康托尔集和谢尔宾斯基地毯在三维空间的推广

构造特点

  1. 画出一个立方体
  2. 将它等分三层(底层,中层,顶层)即等分27个完全相同的小立方体
  3. 掏空每一面中央的小立方体,包括最内层的小立方体
  4. 对剩余的20个小立方体都重复1~3的操作,并渐变填充每个小立方体的三面,使其更有立体感

过程如图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码实现

网上随已有现成源码,但所做封装较多,普遍篇幅较长,本人整理如下的代码量可以缩减到一半以下可读性大大提高。对比另一种方法:单靠不断叠加for循环的实现过程,此方法避免了代码尾段落全是 } 的尴尬,修改也更便捷,只需设定初始迭代值即可,逻辑更清晰易懂

 int x = (int)e.getX();int y = (int)e.getY();int count =6;int d=486,dx=243,dy=243; //正方体边长、右、上侧透视深度

由于绘制立方体不会用到被遮挡的顶角,所以只需记录7个顶角坐标。其中P0点是我们认定的小方块起始绘制的首地址。

public void Menger_Sponge(int x,int y,int d,int dx,int dy,int count){//记录单个方块7个顶角的坐标Point p0 = new Point(x,y);Point p1 = new Point(p0.x+d,p0.y);Point p2 = new Point(p1.x,p1.y+d);Point p3 = new Point(p2.x-d,p2.y);Point p4 = new Point(p0.x+dx,p0.y-dy);Point p5 = new Point(p1.x+dx,p1.y-dy);Point p6 = new Point(p2.x+dx,p2.y-dy);count--; //递归次数减1if(count>=0){//递归到底层各小方块的首地址Menger_Sponge(p0.x+2*dx/3,p0.y-2*dy/3+2*d/3,d/3,dx/3,dy/3,count);Menger_Sponge(p0.x+2*dx/3+d/3,p0.y-2*dy/3+2*d/3,d/3,dx/3,dy/3,count);Menger_Sponge(p0.x+2*dx/3+2*d/3,p0.y-2*dy/3+2*d/3,d/3,dx/3,dy/3,count);Menger_Sponge(p0.x+dx/3,p0.y-dy/3+2*d/3,d/3,dx/3,dy/3,count);Menger_Sponge(p0.x+dx/3+2*d/3,p0.y-dy/3+2*d/3,d/3,dx/3,dy/3,count);Menger_Sponge(p0.x,p0.y+2*d/3,d/3,dx/3,dy/3,count);Menger_Sponge(p0.x+d/3,p0.y+2*d/3,d/3,dx/3,dy/3,count);Menger_Sponge(p0.x+2*d/3,p0.y+2*d/3,d/3,dx/3,dy/3,count);//递归到中层各小方块的首地址Menger_Sponge(p0.x+2*dx/3,p0.y-2*dy/3+d/3,d/3,dx/3,dy/3,count);Menger_Sponge(p0.x+2*dx/3+2*d/3,p0.y-2*dy/3+d/3,d/3,dx/3,dy/3,count);Menger_Sponge(p0.x,p0.y+d/3,d/3,dx/3,dy/3,count);Menger_Sponge(p0.x+2*d/3,p0.y+d/3,d/3,dx/3,dy/3,count);//递归到顶层各小方块的首地址Menger_Sponge(p0.x+2*dx/3,p0.y-2*dy/3,d/3,dx/3,dy/3,count);Menger_Sponge(p0.x+2*dx/3+d/3,p0.y-2*dy/3,d/3,dx/3,dy/3,count);Menger_Sponge(p0.x+2*dx/3+2*d/3,p0.y-2*dy/3,d/3,dx/3,dy/3,count);Menger_Sponge(p0.x+dx/3,p0.y-dy/3,d/3,dx/3,dy/3,count);Menger_Sponge(p0.x+dx/3+2*d/3,p0.y-dy/3,d/3,dx/3,dy/3,count);Menger_Sponge(p0.x,p0.y,d/3,dx/3,dy/3,count);Menger_Sponge(p0.x+d/3,p0.y,d/3,dx/3,dy/3,count);Menger_Sponge(p0.x+2*d/3,p0.y,d/3,dx/3,dy/3,count);}else{//填充正面矩形Polygon poly1 = new Polygon();poly1.addPoint(p0.x, p0.y);poly1.addPoint(p1.x, p1.y);poly1.addPoint(p2.x, p2.y);poly1.addPoint(p3.x, p3.y);g.setColor(new Color(150,0,0));g.fillPolygon(poly1);//填充右面矩形Polygon poly2 = new Polygon();poly2.addPoint(p1.x, p1.y);poly2.addPoint(p2.x, p2.y);poly2.addPoint(p6.x, p6.y);poly2.addPoint(p5.x, p5.y);g.setColor(new Color(200,0,0));g.fillPolygon(poly2);//填充上面矩形Polygon poly3 = new Polygon();poly3.addPoint(p0.x, p0.y);poly3.addPoint(p1.x, p1.y);poly3.addPoint(p5.x, p5.y);poly3.addPoint(p4.x, p4.y);g.setColor(new Color(100,0,0));g.fillPolygon(poly3);}}

绘制结果

在这里插入图片描述
这是迭代3次产生的结果,需要注意的是,三等分边长可能会出现浮点数,故建议按照3的倍数来设定初始值,以防各小方块分离的情况。

结尾

不论一维的cantor集,还是二维的Sierpinski地毯,又或者三维的Menger sponge绘制,迭代的思路无非都遵循了分形图案的特点:每个局部的形状都是整体图案缩小的效果,局部再分形也同样符合。
所以包括L-树,科赫雪花等分形图案的绘制我们也能如法炮制。

问题

门格海绵的绘制中,时间复杂度大,随着迭代次数增加,耗时明显变多有没有更好的方法可以解决这种问题呢?
例如:立方体的8个顶点我们只需要保存7个,立方体的6个面我们只需要绘制出3个,迭代过程中的小立方体有些是被遮挡不需要绘制的,如果我们能有更好的算法,一次性画出迭代的门格海绵,那么这个问题可以得到很好的解决。


http://chatgpt.dhexx.cn/article/qBPYvNAA.shtml

相关文章

分形之门格海绵

门格海绵解决思路: 1. 迭代如何实现 2. 立方体该怎么画 3. 实现门格海绵代码 4. 画图板门格海绵代码 1. 迭代如何实现 为了实现从1图—>2图—>3图效果,我们就要想到用迭代去实现. 因为像3图这样的图形,是由若干个2图这样的基本图形组成的 那么,怎样实现…

JAVA学习日志之门格海绵

门格海绵的结构可以用以下方法形象化: 从一个正方体开始。(第一个图像) 把正方体的每一个面分成9个正方形。这将把正方体分成27个小正方体,像魔方一样。 把每一面的中间的正方体去掉,把最中心的正方体也去掉&#xff0…

复杂分形,简单规则:门格海绵世界探秘

连绵的山川、飘浮的云朵、岩石的断裂口、布朗粒子运动的轨迹、树冠、花菜、大脑皮层……这些部分与整体以某种方式相似的形体,可以说,就是“分形”的要义了,也恰恰是这些“不规则的”、“分散的”、“支离破碎的”物体又重新让我们认识了自然…

JQData | 高校版使用教程,30秒安装完成,自带Python环境

本地量化金融数据JQData,是聚宽数据团队专门为金融机构、学术团体和量化研究者们提供的本地量化金融数据服务。自有版权,支持国内多家头部券商实盘交易。历经15万量化研究者与数百家机构使用验证。 JQData目前已支持国内30 高校,本次更新&…

JQData + matplotlib 实现回测日志的交易细节可视化 量化数据接口

原文:https://zhuanlan.zhihu.com/p/49051899 前言: 做量化交易的朋友都知道回测的重要性,回测结果是衡量一个量化交易策略是否靠谱的重要依据。回测平台会按历史行情数据模拟成交,并将回测结果汇总成报告。 在很多时候&#xf…

Note: Python学习笔记 -- Anaconda install jqdata

运行代码下列代码,提示错误 没有安装 jqdata。打开Anaconda Prompt 输入 pip install jqdata 提示cannot find command git然后百度了半天,有人说 pip install git 出错可以使用 conda install git 但是依然出错。最后去官网下载了Git:https://git-scm.…

jq使用教程01_最贴心教程,安装JQData全靠这篇指南

Hi, 各位亲爱的小伙伴们! 近来听说有部分小伙伴在安装JQData时遇到了点小麻烦,导致最后没有安装成功,为了帮助小伙伴们快速成功安装JQData,小编今天来为大家排一下“雷”,希望能帮到你们哟 (・ω&#xff6…

事件驱动的选股小工具(JQData)

昨天发改委下发了《关于积极推进风电、光伏发电无补贴平价上网有关工作的通知》,也不知道对股市是利空还是利多。连夜做了一个搜索公司经营范围的小工具,看看那些股票受到影响。 以后还可以增加筛选条件,比如财务指标,剔除ST股票,…

股票python量化交易008-JoinQuant中JQData的使用

查阅JoinQuant中JQData的使用文档python代码实现导入JQData,并认证用户身份。认证完毕显示“auth success”后即可使用 from jqdatasdk import *; auth(ID,Password);#ID是申请时所填写的手机号;Password为聚宽官网登录密码 # 查询jqdata的调用次数情况 surplus_count = g…

jqdata pyechart: 用grid双图实现k线带图成交 — by QUANTAXIS

from jqdatasdk import * from pyecharts import Kline,Bar,Grid 首先我们先应JQDATA 的活动演示一下如何调用pyecharts 画图 auth(acc,password) dataget_price(000001.XSHE) auth success先打印下 data 我们可以看到 jqdata返回的格式是 一个单index的Dataframe data.he…

Quant | JQData使用API简单梳理(二)

聚宽平台实际上提供了两种查询数据的方法,第一种是线上在聚宽平台可以使用的API:jqdata,另外一种则是本地的接口:JQData,是的,你没有看错,只是大小写的不同,搞得一开始我以为完全是同一种。jqdata可以线上通过import jqdata来引入数据接口,本地的JQData则是通过import…

jqdata(data是什么文件格式)

期货交易中bar和tick是什么意思 Bar 的概念 在一定时间段内的时间序列就构成了一根 K 线(日本蜡烛图),单根 K 线被称为 Bar。 如果是一分钟内的 Tick 序列,即构成一根分钟 K 线,又称分钟 Bar; 如果是一天内的分钟序列,即构成一根日…

JQData | 量化界最好用的本地量化金融数据(free free~)

什么是本地量化金融数据 - JQData ? 使用JQData本地量化金融数据服务,可快速查看、计算或接入金融数据信息,解决本地、web、自研金融终端调用数据的需求。支持python多版本及多操作系统。为财经类企业、金融机构、学术研究机构和量化爱好者们…

获取股票数据【使用JQData查询行情数据、财务指标、估值指标】

了解股票: 在上一次量化小科普【什么是量化?常用的股票量化指标、如何搭建量化交易系统】对于量化的概念有了一个基本认识,其中量化的主体在这门课程的学习中是“股票”,而当别人问你:“什么是股票?”&…

JQData安装的问题(本地调用的量化金融数据接口-免费)

JQData简介(1)JQData是聚宽数据团队专门为有志于从事量化投资的金融机构、研究人员以及个人量化爱好者提供的本地量化金融数据。用户只需在本地Python环境下安装JQData数据包,输入三行代码,即可调用由聚宽数据团队专业生产的全套量化金融数据,让你轻松告别平台限制,灵活安…

JQData安装(转)

首先,JQData是基于python的一个数据包,所以安装JQData的第一步是安装Python (没有接触过python或者python基础不好的小伙伴,可以关注聚宽量化课堂的python讲堂进行python学习)。 对于python安装包的选择,…

JQData安装的问题(只解决安装的问题)

1. JQData简介 (1)JQData是聚宽数据团队专门为有志于从事量化投资的金融机构、研究人员以及个人量化爱好者提供的本地量化金融数据。用户只需在本地Python环境下安装JQData数据包,输入三行代码,即可调用由聚宽数据团队专业生产的…

JQData-本地调用的量化金融数据接口(免费)

什么是聚宽数据-JQData? 使用JQData金融数据服务,可快速查看、计算或接入金融数据信息,解决本地、web、自研金融终端调用数据的需求。支持python多版本及多操作系统。为财经类企业、金融机构、学术研究机构和量化爱好者们提供一站式财经信息服务及数据解决方案。 提供哪些…

JQData安装 | 最贴心教程,安装JQData全靠这篇指南

转自 JQData安装 | 最贴心教程,安装JQData全靠这篇指南 Hi, 各位亲爱的小伙伴们! 首先,感谢聚宽小编 JQData01 给我开放了更多的数据访问资源 近来听说有部分小伙伴在安装JQData时遇到了点小麻烦,导致最后没有安装成功&#xff0c…

如何理解敏捷开发

目录 什么是敏捷开发 2.0 常用的 4 种开发模式 瀑布式开发 迭代式开发 螺旋式开发 敏捷软件开发 4 种开发模式总结 什么是 DevOps 精益管理的7个原则 DevOps的开发流程 提交 编译 单元测试 部署到测试环境中 预生产测试 部署到生产环境 敏捷开发 2.0 解决的问…