利用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),名字来源于它的首创者——美国佐治亚理工学院的巴恩斯利教授。
为了生成植物的形状,巴恩斯利教授把两种运算规则相结合:确定性算法与随机性算法。确定性算法的公式如下:
随机性算法为多个确定性算法被选中的概率。
比如上面的谢尔宾斯基三角形用这个方法写可以写作:
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巴恩斯利蕨的计算公式表格如下:
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