利用matlab绘制简单IFS图形(Sierpinski三角形和BarnsleyFern巴恩斯利蕨)

利用matlab绘制简单IFS图形(Sierpinski谢尔宾斯基三角形和BarnsleyFern巴恩斯利蕨)

一、SierpinskiTriangle谢尔宾斯基三角形

谢尔宾斯基三角形(英语:Sierpinski triangle)是一种分形,由波兰数学家谢尔宾斯基在1915年提出。它的维度为log(3)/log(2)=1.585。(来自百度

下面用迭代的方式绘制谢尔宾斯基三角形,方法如下:

在平面上任取三个不共线的点A、B、C作为三角形的3个顶点,之后选取另一点作为当前点。
1计算当前点与随机某一顶点的中点O
2绘制该中点O,并将该点作为新的当前点。重复步骤1
在这里插入图片描述
效果如下:
在这里插入图片描述
虽然初始当前点在三角形之外,但是随着迭代,很快便具有三角形的外观。随着时间的增加呈现出谢尔宾斯基三角形。

谢尔宾斯基三角形具有空间的自相似性。比如根据上面的算法得到的正三角形如下图所示(共计2^17个点)。
在这里插入图片描述
对上图进行灰度化显示,按分辨率大小划分区间,将点数多的区间标记为白色,将点数少的区间标记为黑色。逐渐提高图像分辨率,可以得到如下动图:
在这里插入图片描述
matlab代码如下:

%谢尔宾斯三角形
%给定初始3点
Tripots=rand(3,2);
Tripots=[0,1;1*sin(2*pi/3),1*cos(2*pi/3);1*sin(4*pi/3),1*cos(4*pi/3)];

%定义SierpinskiTriangle三角形点数
N=2^17;%定义1000个点
SierpinskiTriangle=zeros(N+3,2);
SierpinskiTriangle(1:3,:)=Tripots;
%定义参考点
ReferencePoint=rand(1,2);

for j=1:N
    %选取参考点与随机角点的中点,作为新的参考点
    ReferencePoint=(Tripots(randi([1,3],1),:)+ReferencePoint)/2;
    %记录在SierpinskiTriangle中
    SierpinskiTriangle(3+j,:)=ReferencePoint;
end

scatter(SierpinskiTriangle(:,1),SierpinskiTriangle(:,2),0.1,'filled')
axis off

灰度图绘制利用hist3()函数。

参考:
1数学实验(李尚志)P125
2知乎:谢尔宾斯基三角形能用编程写出来么?该怎么写?https://www.zhihu.com/question/53448865

二、BarnsleyFern巴恩斯利蕨

巴恩斯利蕨(Barnsley fern),名字来源于它的首创者——美国佐治亚理工学院的巴恩斯利教授。

为了生成植物的形状,巴恩斯利教授把两种运算规则相结合:确定性算法与随机性算法。确定性算法的公式如下:
f ( x , y ) = [ a b c d ] [ x y ] + [ e f ] f(x,y)=\begin{bmatrix} a & b\\ c & d \end{bmatrix}\begin{bmatrix} x\\ y \end{bmatrix}+\begin{bmatrix} e\\ f \end{bmatrix}
随机性算法为多个确定性算法被选中的概率。

比如上面的谢尔宾斯基三角形用这个方法写可以写作:

a b c d e f p
1 0.5 0 0 0.5 sin(2* pi/3*0) cos(2* pi/3*0) 1/3
2 0.5 0 0 0.5 sin(2* pi/3*1) cos(2* pi/3*1) 1/3
3 0.5 0 0 0.5 sin(2* pi/3*2) cos(2* pi/3*2) 1/3

有1/3的概率被选中第一个顶点,1/3概率被选中第二个顶点,1/3概率被选中第三个顶点。

BarnsleyFern巴恩斯利蕨的计算公式表格如下:

扫描二维码关注公众号,回复: 6043746 查看本文章
a b c d e f p
1 0.00 0.00 0.00 0.16 0.500 0.000 0.01
2 0.85 0.04 -.04 0.85 0.075 0.180 0.85
3 0.20 -.26 0.23 0.22 0.400 0.045 0.07
4 -.15 0.28 0.26 0.24 0.575 -.086 0.07

绘制的效果如下:
在这里插入图片描述
可见生成上述复杂的图形所需要的信息,只有上述表格和对应的规则。
matlab代码如下:

clear
close
%巴恩斯利蕨(Barnsley fern)
A=zeros(2,2,4);
B=zeros(2,1,4);
%输入A,B 参数1
% A(:,:,1)=[0.00,0.00;0.00,0.16];B(:,:,1)=[0.00;0.00];
% A(:,:,2)=[0.85,0.04;-0.04,0.85];B(:,:,2)=[0.00;1.60];
% A(:,:,3)=[0.20,-0.26;0.23,0.22];B(:,:,3)=[0.00;1.60];
% A(:,:,4)=[-0.15,0.28;0.26,0.24];B(:,:,4)=[0.00;0.44];
%输入A,B 参数2
A(:,:,1)=[0.00,0.00;0.00,0.16];B(:,:,1)=[0.500;0.000];
A(:,:,2)=[0.85,0.04;-.04,0.85];B(:,:,2)=[0.075;0.180];
A(:,:,3)=[0.20,-.26;0.23,0.22];B(:,:,3)=[0.400;0.045];
A(:,:,4)=[-.15,0.28;0.26,0.24];B(:,:,4)=[0.575;-.086];
%输入p
p=[0.01;0.85;0.07;0.07];

cump=[0;cumsum(p)];
XY=rand(2,1);
N=2^19;
Pt=zeros(2,N);

for j=1:N
    Pt(:,j)=XY;
    x=randbyp(cump);
    XY=A(:,:,x)*XY+B(:,:,x);
end

scatter(Pt(1,:),Pt(2,:),0.2,'g','filled')
axis off
print('-dpng','-r1200','巴恩斯利蕨2')

%按概率生成随机整数
function x=randbyp(p)
%p是每个整数对应的累加概率
y=rand(1);
x=0;
for j=1:length(p)
    x=x+j*( y>p(j) && y<=p(j+1) );
end
end

参考:
科学松鼠会:http://songshuhui.net/archives/39756
java分形生成https://introcs.cs.princeton.edu/java/22library/

3.多边形迭代演示

对于四边形,利用第一章的生成方法不能很好的去生成有规律的图案,需要辅助构造一个新的生成规则:
引入除四边形外4个点的第五个点——四边形中心点。

下图是第5个点对应规则的概率,由0逐渐增加为1的动态图,可以看到在当等于1和等于0的时候都不能很好的出现分形现象,在中间位置才会出现较为明显的图案。
在这里插入图片描述
代码如下:

%四边形
clear
close
%SierpinskiTriangle
A=zeros(2,2,5);
B=zeros(2,1,5);
A(:,:,1)=[0.50,0.00;0.00,0.50];B(:,:,1)=[1;1];
A(:,:,2)=[0.50,0.00;0.00,0.50];B(:,:,2)=[1;-1];
A(:,:,3)=[0.50,0.00;0.00,0.50];B(:,:,3)=[-1;-1];
A(:,:,4)=[0.50,0.00;0.00,0.50];B(:,:,4)=[-1;1];
A(:,:,5)=[0.50,0.00;0.00,0.50];B(:,:,5)=[0;0];

for pl=0.25:-0.01:0
    
    p=[pl;pl;pl;pl;1-4*pl];
    
    cump=[0;cumsum(p)];
    XY=rand(2,1);
    N=2^17;
    Pt=zeros(2,N);
    
    for j=1:N
        Pt(:,j)=XY;
        x=randbyp(cump);
        XY=A(:,:,x)*XY+B(:,:,x);
    end
    
    scatter(Pt(1,:),Pt(2,:),0.2,'filled')
    xlim([-2,2]);ylim([-2,2]);
    pause(0.1)

end

%按概率生成随机整数
function x=randbyp(p)
%p是每个整数对应的累加概率
y=rand(1);
x=0;
for j=1:length(p)
    x=x+j*( y>p(j) && y<=p(j+1) );
end
end

对于5边形,则可以直接看到分型图案为:
在这里插入图片描述

对于多边形,则逐渐出现趋同的现象,比如下图为100边形的图案,出现了类似甜甜圈的分布,但是看不到明显的分型现象:
在这里插入图片描述
绘制正多边形的代码如下:

clear
clc


L=5;%边数
N=2^13;%点数

for j=1:L
    A(:,:,j)=[0.50,0.00;0.00,0.50];B(:,:,j)=[sin(2*pi/L*j);cos(2*pi/L*j)];
end
cump=(0:1/L:1)';
XY=rand(2,1);
Pt=zeros(2,N);

for j=1:N
    Pt(:,j)=XY;
    x=randi([1,L],1);
    XY=A(:,:,x)*XY+B(:,:,x);
end

scatter(Pt(1,:),Pt(2,:),0.3,'filled')
axis off
print('-dpng','-r300','多边形')

参考:
混沌分形之谢尔宾斯基(Sierpinski)https://www.cnblogs.com/WhyEngine/p/4069094.html

猜你喜欢

转载自blog.csdn.net/weixin_42943114/article/details/87552879