该模型是1982年由Alain Fournier, DonFussell和Loren Carpenter提出的,它能有效地模拟海岸线和山等自然景象。
为了克服传统模型技术中依赖观察距离的局限性,随机插值模型不是事先决定各种图素和尺度,而是用一个随机过程的采样路径作为构造模型的手段。例如,构造二维海岸线的模型可以
这样下去可得到一条曲折的有无穷细节回归的海岸线,其曲折程度由随机偏移量控制。它也决定了分数维的大小:
图一
在三维情况下可通过类似过程构造山的模型,一般通过多边形(简单的如三角形)细分的方法。可以在一个三角形的3条边上随机各取一点,并沿垂直方向偏移一定距离后得到新的3个点,再连接成4个三角形,如此继续,即可形成褶皱的山峰。山的褶皱程度由分数维控制:
图二
下面以画出Sierpinski三角形举例
步骤
a.给三角形的3个顶点,和一个当前点;
b.随机选择三角形的某一个顶点,计算出它与当前点的中点位置;
c.将计算出的中点做为当前点,再重新执行操作a。
#include
#include
#include
#include
#define PI 3.14159265
int max_iter=10000;//迭代次数
double point[3][2]={
0,100*tan(PI/3),
100,0,
200,100*tan(PI/3)
};//三角形三个顶点坐标
void Sierpinski(double x0,double y0,int k){
if(k>max_iter) return;
int rnum=rand()%3;//设置概率
if(rnum==0){
x0=(x0+point[0][0])*0.5;
y0=(y0+point[0][1])*0.5;
}
else if(rnum==1){
x0=(x0+point[1][0])*0.5;
y0=(y0+point[1][1])*0.5;
}
else{
x0=(x0+point[2][0])*0.5;
y0=(y0+point[2][1])*0.5;
}
k++;
putpixel(x0,y0,YELLOW);
Sierpinski(x0,y0,k);
}
int main(){
initgraph(1000,1000);
double x0=100,y0=0;//给一个当前点 x0,y0
Sierpinski(x0,y0,0);
getch();
closegraph();
return 0;
}
概念:
迭代函数系统是从一个坐标系到另一个坐标系的映射系统。迭代函数系统是以下述方式工作的:取空间中任一点 Z 0 Z_0 Z0,以 P i P_i Pi 概率选取变换 M i M_i Mi,作变换 Z i Z_i Zi= M i M_i Mi( Z 0 Z_0 Z0),再以 P i P_i Pi的概率选取变换 M i M_i Mi,对 Z 1 Z_1 Z1做变换 Z 2 Z_2 Z2= M i M_i Mi( Z 1 Z_1 Z1),以此下去,得到一个无数点集。
IFS 的压缩映射 w i w_i wi 的参数设计 :
由分形图的相似结构, 每一个压缩映射 w i w_i wi是 由平移、 旋转和比例 3 种变换以及它们的复合变换构成的仿射变换, 二维形式为 :
三种变换是:
其中参数 a i a_i ai , b i b_i bi , c i c_i ci , d i d_i di 由旋转 、 比例变换所决定的实数 ; e i e_i ei, f i f_i fi 由平移变换所决定的实数 。三维形是由相应的三维空间几何变换复合而成。
IFS 吸引子自然景观的模拟总是在一个矩形区域内进行 , 取度量空间 ([ 0 , 1] × [ 0 , 1] , d), 由于 w i w_i wi 是压缩变换, w i w_i wi ([ 0 , 1] × [ 0 , 1] ) [ 0 , 1] × [ 0 , 1] 。因此, 参数 a i a_i ai , b i b_i bi , c i c_i ci , e i e_i ei, f i f_i fi的取值范围在 [ -1 , 1] ; e i e_i ei 的取值影响植物x 方向的偏离程度, f i f_i fi,的取值影响植物在竖直y方向的生长程度 , 一般取值为正。
IFS 中概率 p1 , … , pn 的参数设计:
p1 , p2 , …, pn 的大小分配并不影响最终吸引子, 也就是绘制的图形完全由 w i w_i wi (i =1 , 2 , …, n)确 定 , 与 p1 , p2 , … , pn 无关 , p1 , p2 , …, pn 只是为计算机编程绘图提供了极大的方便 , p1 , p2 , …, pn 的大小分配只影响绘图的速度, 即迭代次数。
IFSP码举例:
Sierpinski 三角形的IFS代码:
w | a | b | c | d | e | f | p |
---|---|---|---|---|---|---|---|
1 | 0.5 | 0 | 0 | 0.5 | 0 | 0 | 0.33 |
2 | 0.5 | 0 | 0 | 0.5 | 0.5 | 0 | 0.33 |
3 | 0.5 | 0 | 0 | 0.5 | 0.25 | 0.5 | 0.34 |
《分形图的 IFS 码设计》这篇文章中包含IFS 参数设计的详细介绍,可参阅【直接下载】
https://download.csdn.net/download/qq_43606914/12446875
#include
#include
#include
int Iter=10000;
double a[4][7]={
0, 0, 0, 0.170, 0, 0, 0.01 ,
0.155,-0.235,0.196,0.186,0,0.9,0.07,
-0.155,0.235,0.196,0.186,0,0.4,0.07,
0.850,0.025,-0.025,0.850,0,0.9,0.85
};
void IFS_Tree(double x0,double y0,int k){
if(k>Iter) return;
int tmp=rand()%100;
if(tmp<=1){
x0=a[0][0]*x0+a[0][1]*y0+a[0][4];
y0=a[0][2]*x0+a[0][3]*y0+a[0][5];
}
else if(tmp<=8){
x0=a[1][0]*x0+a[1][1]*y0+a[1][4];
y0=a[1][2]*x0+a[1][3]*y0+a[1][5];
}
else if(tmp<=15){
x0=a[2][0]*x0+a[2][1]*y0+a[2][4];
y0=a[2][2]*x0+a[2][3]*y0+a[2][5];
}
else{
x0=a[3][0]*x0+a[3][1]*y0+a[3][4];
y0=a[3][2]*x0+a[3][3]*y0+a[3][5];
}
putpixel(x0*100+300,600-y0*100,WHITE);
k++;
IFS_Tree(x0,y0,k);
}
int main(){
initgraph(1000,1000);
srand((unsigned)time(NULL));
double x0,y0=0;
x0 = rand()%200+1;
y0 = rand()%200+1;
IFS_Tree(x0,y0,0);
getch();
closegraph();
return 0;
}
L系统(short for Lindenmayer systems)是比较新的制作分形的方法。这项技术是Aristrid Lindenmayer在1968提出来的,最早是用来研究植物生长的生物模型。原理即是用字符串来描述一棵树,一朵花,甚至雪花等等。
L-system 包含三个部分:
L系统通常使用以下字母:“ FG ±[]”,表示:
F:画一条线并向前移动
G:前进(不画线)
+:右转
-:左转
[:保存当前位置
]:恢复上一个位置