混沌分形之迭代函数系统(IFS)
IFS是分形的重要分支。它是分形图像处理中最富生命力而且最具有广阔应用前景的领域之一。这一工作最早可以追溯到Hutchinson于1981年对自相似集的研究。美国科学家M.F.Barnsley于1985年发展了这一分形构型系统,并命名为迭代函数系统(Iterated Function System,IFS),后来又由Stephen Demko等人将其公式化,并引入到图像合成领域中。IFS将待生成的图像看做是由许多与整体相似的(自相似)或经过一定变换与整体相似的(自仿射)小块拼贴而成。
算法:
1.设定一个起始点(x0,y0)及总的迭代步数。
2.以概率P选取仿射变换W,形式为
X1=a*x0 + b*y0 + e
Y1=c*x0 + d*y0 + f
或
X1=(a * x0*cosf(c/180)) - (b * y0*sinf(d/180)) + e
Y1=(a * x0*sinf(c/180)) + (b * y0*cosf(d/180)) + f
3.以W作用点(x0,y0),得到新坐标(x1,y1)。
4.令x0=x1,y0=y1。
5.在屏幕上打出(x0,y0)。
6.重返第2步,进行下一次迭代,直到迭代次数大于总步数为止。
(1)三角形
class IFSTriangle : public FractalEquation
{
public:
IFSTriangle()
{
m_StartX = 0.0f;
m_StartY = 0.0f;
m_StartZ = 0.0f; m_ParamA = 0.0f;
m_ParamB = 0.5f; //'IFS码赋值
m[][] = 0.5f; m[][] = ; m[][] = ; m[][] = 0.5f; m[][] = ; m[][] = ; m[][] = 0.333f;
m[][] = 0.5f; m[][] = ; m[][] = ; m[][] = 0.5f; m[][] = 0.5f; m[][] = ; m[][] = 0.333f;
m[][] = 0.5f; m[][] = ; m[][] = ; m[][] = 0.5f; m[][] = 0.25f; m[][] = 0.5f; m[][] = 0.334f;
} void IterateValue(float x, float y, float z, float& outX, float& outY, float& outZ) const
{
float a, b, c, d, e, f; //'仿射变幻中的系数 float R = (float)rand()/RAND_MAX; if (R <= m[][])
{
a = m[][]; b = m[][]; c = m[][]; d = m[][]; e = m[][]; f = m[][];
}
else if (R <= m[][] + m[][])
{
a = m[][]; b = m[][]; c = m[][]; d = m[][]; e = m[][]; f = m[][];
}
else
{
a = m[][]; b = m[][]; c = m[][]; d = m[][]; e = m[][]; f = m[][];
} outX = (a * x) + (b * y) + e*FRACTAL_RADIUS;
outY = (c * x) + (d * y) + f*FRACTAL_RADIUS;
outZ = z;
} bool IsValidParamA() const {return true;}
bool IsValidParamB() const {return true;} void SetParamA(float v)
{
m_ParamA = v;
m[][] = v;
} void SetParamB(float v)
{
m_ParamB = v;
m[][] = v;
m[][] = v;
} private:
float m[][]; // '存放IFS码
};

这里生成的是谢尔宾斯基三角形,但可以通过参数设置对其变形


(2)皇冠
class IFSCrown : public FractalEquation
{
public:
IFSCrown()
{
m_StartX = 0.0f;
m_StartY = 0.0f;
m_StartZ = 0.0f; m_ParamA = 2.0f; //'IFS码赋值
m[][] = 0.5f; m[][] = 0.5f; m[][] = ; m[][] = ; m[][] = ; m[][] = ; m[][] = 0.2f;
m[][] = 0.5f; m[][] = 0.5f; m[][] = ; m[][] = ; m[][] = 0.5f; m[][] = ; m[][] = 0.2f;
m[][] = 0.25f; m[][] = 0.25f; m[][] = ; m[][] = ; m[][] = 2.0f; m[][] = 2.0f;m[][] = 0.3f;
m[][] = 0.25f; m[][] = 0.25f; m[][] = ; m[][] = ; m[][] = -1.0f;m[][] = 2.0f;m[][] = 0.3f;
} void IterateValue(float x, float y, float z, float& outX, float& outY, float& outZ) const
{
float a, b, c, d, e, f; //'仿射变幻中的系数 float R = (float)rand()/RAND_MAX; if (R <= m[][])
{
a = m[][]; b = m[][]; c = m[][]; d = m[][]; e = m[][]; f = m[][];
}
else if (R <= m[][] + m[][])
{
a = m[][]; b = m[][]; c = m[][]; d = m[][]; e = m[][]; f = m[][];
}
else if (R <= m[][] + m[][] + m[][])
{
a = m[][]; b = m[][]; c = m[][]; d = m[][]; e = m[][]; f = m[][];
}
else
{
a = m[][]; b = m[][]; c = m[][]; d = m[][]; e = m[][]; f = m[][];
} outX = (a * x*cosf(c/)) - (b * y*sinf(d/)) + e*FRACTAL_RADIUS;
outY = (a * x*sinf(c/)) + (b * y*cosf(d/)) + f*FRACTAL_RADIUS;
outZ = z;
} bool IsValidParamA() const {return true;} void SetParamA(float v)
{
m_ParamA = v;
m[][] = v;
m[][] = v;
m[][] = - v;
m[][] = v;
} private:
float m[][]; // '存放IFS码
};


(3)芦苇
// 芦苇
class IFSBulrush : public FractalEquation
{
public:
IFSBulrush()
{
m_StartX = 0.0f;
m_StartY = 0.0f;
m_StartZ = 0.0f; m_ParamA = 10.0f; float k = m_ParamA*100.0f; //'IFS码赋值
m[][] = 0.5f; m[][] = 0.5f; m[][] = ; m[][] = ; m[][] = ; m[][] = ; m[][] = 0.3f;
m[][] = 0.5f; m[][] = 0.5f; m[][] = k; m[][] = k; m[][] = ; m[][] = k/; m[][] = 0.3f;
m[][] = 0.5f; m[][] = 0.5f; m[][] = ; m[][] = ; m[][] = 0.5f; m[][] = ; m[][] = 0.4f;
} void IterateValue(float x, float y, float z, float& outX, float& outY, float& outZ) const
{
float a, b, c, d, e, f; //'仿射变幻中的系数 float R = (float)rand()/RAND_MAX; if (R <= m[][])
{
a = m[][]; b = m[][]; c = m[][]; d = m[][]; e = m[][]; f = m[][];
}
else if (R <= m[][] + m[][])
{
a = m[][]; b = m[][]; c = m[][]; d = m[][]; e = m[][]; f = m[][];
}
else
{
a = m[][]; b = m[][]; c = m[][]; d = m[][]; e = m[][]; f = m[][];
} outX = (a * x*cosf(c/)) - (b * y*sinf(d/)) + e*FRACTAL_RADIUS;
outY = (a * x*sinf(c/)) + (b * y*cosf(d/)) + f*FRACTAL_RADIUS;
outZ = z;
} bool IsValidParamA() const {return true;} void SetParamA(float v)
{
m_ParamA = v;
float k = m_ParamA*100.0f;
m[][] = k;
m[][] = k;
m[][] = k/;
} private:
float m[][]; // '存放IFS码
};



(4)万花筒
// 万花筒
class IFSPhantoscope : public FractalEquation
{
public:
IFSPhantoscope()
{
m_StartX = 0.0f;
m_StartY = 0.0f;
m_StartZ = 0.0f; m_ParamA = 2.0f; float k = m_ParamA*100.0f; //'IFS码赋值
m[][] = 0.2f; m[][] = 0.2f; m[][] = ; m[][] = ; m[][] = 0.7f; m[][] = ; m[][] = 0.2f;
m[][] = 0.2f; m[][] = 0.2f; m[][] = ; m[][] = ; m[][] =-0.7f; m[][] = ; m[][] = 0.2f;
m[][] = 0.2f; m[][] = 0.2f; m[][] = ; m[][] = ; m[][] = ; m[][] = 0.7f; m[][] = 0.2f;
m[][] = 0.2f; m[][] = 0.2f; m[][] = ; m[][] = ; m[][] = ; m[][] = -0.7f; m[][] = 0.2f;
m[][] = 0.85f; m[][] = 0.85f; m[][] = k; m[][] = k; m[][] = ; m[][] = ; m[][] = 0.2f;
} void IterateValue(float x, float y, float z, float& outX, float& outY, float& outZ) const
{
float a, b, c, d, e, f; //'仿射变幻中的系数 float R = (float)rand()/RAND_MAX; if (R <= m[][])
{
a = m[][]; b = m[][]; c = m[][]; d = m[][]; e = m[][]; f = m[][];
}
else if (R <= m[][] + m[][])
{
a = m[][]; b = m[][]; c = m[][]; d = m[][]; e = m[][]; f = m[][];
}
else if (R <= m[][] + m[][] + m[][])
{
a = m[][]; b = m[][]; c = m[][]; d = m[][]; e = m[][]; f = m[][];
}
else if (R <= m[][] + m[][] + m[][] + m[][])
{
a = m[][]; b = m[][]; c = m[][]; d = m[][]; e = m[][]; f = m[][];
}
else
{
a = m[][]; b = m[][]; c = m[][]; d = m[][]; e = m[][]; f = m[][];
} outX = (a * x*cosf(c/)) - (b * y*sinf(d/)) + e*FRACTAL_RADIUS;
outY = (a * x*sinf(c/)) + (b * y*cosf(d/)) + f*FRACTAL_RADIUS;
outZ = z;
} bool IsValidParamA() const {return true;} void SetParamA(float v)
{
m_ParamA = v;
float k = m_ParamA*100.0f;
m[][] = k;
m[][] = k;
} private:
float m[][]; // '存放IFS码
};


(5)Tree
class IFSTree : public FractalEquation
{
public:
IFSTree()
{
m_StartX = 0.0f;
m_StartY = 0.0f;
m_StartZ = 0.0f; //'IFS码赋值
m[][] = 0.195f; m[][] =-0.488f; m[][] = 0.344f; m[][] = 0.433f; m[][] = 0.4431f; m[][] = 0.2452f; m[][] = 0.25f;
m[][] = 0.462f; m[][] = 0.414f; m[][] =-0.252f; m[][] = 0.361f; m[][] = 0.2511f; m[][] = 0.5692f; m[][] = 0.25f;
m[][] =-0.058f; m[][] =-0.07f; m[][] = 0.453f; m[][] =-0.111f; m[][] = 0.5976f; m[][] = 0.0969f; m[][] = 0.25f;
m[][] =-0.035f; m[][] = 0.07f; m[][] =-0.469f; m[][] =-0.022f; m[][] = 0.4884f; m[][] = 0.5069f; m[][] = 0.2f;
m[][] =-0.637f; m[][] = 0.0f; m[][] = 0.0f; m[][] = 0.501f; m[][] = 0.8562f; m[][] = 0.2513f; m[][] = 0.05f;
} void IterateValue(float x, float y, float z, float& outX, float& outY, float& outZ) const
{
float a, b, c, d, e, f; //'仿射变幻中的系数 float R = (float)rand()/RAND_MAX; if (R <= m[][])
{
a = m[][]; b = m[][]; c = m[][]; d = m[][]; e = m[][]; f = m[][];
}
else if (R <= m[][] + m[][])
{
a = m[][]; b = m[][]; c = m[][]; d = m[][]; e = m[][]; f = m[][];
}
else if (R <= m[][] + m[][] + m[][])
{
a = m[][]; b = m[][]; c = m[][]; d = m[][]; e = m[][]; f = m[][];
}
else if (R <= m[][] + m[][] + m[][] + m[][])
{
a = m[][]; b = m[][]; c = m[][]; d = m[][]; e = m[][]; f = m[][];
}
else
{
a = m[][]; b = m[][]; c = m[][]; d = m[][]; e = m[][]; f = m[][];
} outX = a*x + b*y + e;
outY = c*x + d*y + f;
outZ = z;
} private:
float m[][]; // '存放IFS码
};

这个图形我很喜欢,所以还专门将其生成图像:

(6)大脑
class IFSBrain : public FractalEquation
{
public:
IFSBrain()
{
m_StartX = 0.0f;
m_StartY = 0.0f;
m_StartZ = 0.0f; //'IFS码赋值
//0.03 0 0 0.45 0 0 0.05;
//-0.03 0 0 -0.45 0 0.4 0.15;
//0.56 -0.56 0.56 0.56 0 0.4 0.4;
//0.56 0.56 -0.56 0.56 0 0.4 0.4;
m[][] = 0.03f; m[][] = 0.0f; m[][] = 0.0f; m[][] = 0.45f; m[][] = 0.0f; m[][] = 0.0f; m[][] = 0.05f;
m[][] =-0.03f; m[][] = 0.0f; m[][] = 0.0f; m[][] =-0.45f; m[][] = 0.0f; m[][] = 0.4f; m[][] = 0.15f;
m[][] = 0.56f; m[][] =-0.56f; m[][] = 0.56f; m[][] = 0.56f; m[][] = 0.0f; m[][] = 0.4f; m[][] = 0.4f;
m[][] = 0.56f; m[][] = 0.56f; m[][] =-0.56f; m[][] = 0.56f; m[][] = 0.0f; m[][] = 0.4f; m[][] = 0.4f;
} void IterateValue(float x, float y, float z, float& outX, float& outY, float& outZ) const
{
float a, b, c, d, e, f; //'仿射变幻中的系数 float R = (float)rand()/RAND_MAX; if (R <= m[][])
{
a = m[][]; b = m[][]; c = m[][]; d = m[][]; e = m[][]; f = m[][];
}
else if (R <= m[][] + m[][])
{
a = m[][]; b = m[][]; c = m[][]; d = m[][]; e = m[][]; f = m[][];
}
else if (R <= m[][] + m[][] + m[][])
{
a = m[][]; b = m[][]; c = m[][]; d = m[][]; e = m[][]; f = m[][];
}
else
{
a = m[][]; b = m[][]; c = m[][]; d = m[][]; e = m[][]; f = m[][];
} outX = a*x + b*y + e;
outY = c*x + d*y + f;
outZ = z;
} private:
float m[][]; // '存放IFS码
};

------------------------------------
关于基类FractalEquation的定义及相关软件见:混沌与分形
混沌分形之迭代函数系统(IFS)的更多相关文章
- JavaScript图形实例:迭代函数系统生成图形
迭代函数系统(Iterated Function System,IFS)可以用来创建分形图案,它是分形理论的重要分支,也是分形图形处理中最富生命力而且最具有广阔应用前景的领域之一.这一工作最早可以追溯 ...
- 混沌分形之逻辑斯蒂(Logistic)映射系统
前几天,有个同事看到我生成的一幅逻辑斯蒂分岔图像后,问我:“这是咪咪吗?”我回答:“淫者见淫.”好吧,这里将生成几种分岔映射图形,包括逻辑斯蒂映射系统,正弦映射系统和曼德勃罗映射系统.实际上这几种图形 ...
- javascript学习笔记--迭代函数
概要 这里的迭代函数指的是对数组对象的操作方法,js数组共有五个迭代函数:every.fifter.forEach.map.some. 1.every every方法,返回值为Boolean类型,tr ...
- Haskell 笔记(四)函数系统
函数系统 函数式编程当然少不了函数系统啦,在教程最初的时候就有一个最简单的函数,函数系统贯穿在Haskell全部,Haskell的函数有几个重要的性质. 首先声明一下函数的参数和返回值类型 然后有一个 ...
- Mathematica 迭代函数
学习Mathematica迭代函数的几个画图例子: 1.三角形沿着某一点旋转 verticse = {{0, 0}, {1, 0}, {1/2, Sqrt[3]/2}}; tri = Line[ver ...
- JavaScript的迭代函数与迭代函数的实现
前言 如果对技术很自信,请直接看 实现的源码 如果想回顾一下基础,请按文章顺序阅读 说到迭代方法,最先想到的是什么?forEach还是map,迭代的方法ES5提供了5种方法 以下定义来自 Ja ...
- BMDP为常规的统计分析提供了大量的完备的函数系统,如:方差分析(ANOVA)、回归分析(Regression)、非参数分析(Nonparametric Analysis)、时间序列(Times Series)等等。此外,BMDP特别擅于进行出色的生存分析(Survival Analysis )。许多年来,一大批世界范围内顶级的统计学家都曾今参与过BMDP的开发工作。这不仅使得BMDP的权威性得到
BMDP是Bio Medical Data Processing的缩写,是世界级的统计工具软件,至今已经有40多年的历史.目前在国际上与SAS.SPSS被并称为三大统计软件包.BMDP是一个大 ...
- 混沌分形之马丁(Martin)迭代
我不记得从什么地方看到的这种分形图形生成方式,再到网上找竟然一时没查到任何相关资料.没关系,总之这种图形也很漂亮多变,并且其算法比较简单.只是我最后生成的图像有点瘆人,密集恐惧症患者慎入. 相关代码如 ...
- 文件处理,三元操作符,seek()函数,迭代函数和列表解析,reduce函数
1.文件读取方类型 r,r+,w,x,a, r,读文件 w,写文件,文件内容全部删除,并将新内容从第一行开始赋值 x,写文件,只有文件不存在,可写,文件存在,报错 a,在文件莫问追加信息 r+,w+, ...
随机推荐
- IllegalArgumentException: Unmatched braces in the pattern.
IllegalArgumentException: Unmatched braces in the pattern. 非法参数异常. 不匹配的 吊带 在 样品 中. === 没有管. 项目一直卡在d ...
- 【10.31校内测试】【组合数学】【记忆化搜索/DP】【多起点多终点二进制拆位Spfa】
Solution 注意取模!!! Code #include<bits/stdc++.h> #define mod 1000000007 #define LL long long usin ...
- Docker系列之(一):10分钟玩转Docker
1.前言 进入云计算的时代,各大云提供商AWS,阿里云纷纷推出针对Docker的服务,现在Docker是十分火爆,那么Docker到底是什麽,让我们来体验一下. 2.Docker是什麽 Docker是 ...
- git 用户名和密码保存
git config --global credential.helper store 输入一次后,后续不再需要输入用户名密码
- MySQL错误:TIMESTAMP with implicit DEFAULT value is deprecated
用于存放数据库的文件夹不为空,清空了再来一次!
- HDU 4738 Caocao's Bridges (2013杭州网络赛1001题,连通图,求桥)
Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- EasyNetQ介绍
EasyNetQ 是一个容易使用,坚固的,针对RabbitMQ的 .NET API. 假如你尽可能快的想去安装和运行RabbitMQ,请去看入门指南.EasyNetQ是为了提供一个尽可能简洁的适用与R ...
- 采用ASP.NET IIS 注册工具 (Aspnet_regiis.exe)对web.config实行本地加密
加密原因:我们通常将一些重要的配置信息写在Web.config里面,其中数据库链接就是这样的信息.将这些数据直接明文显示,显然不太安全. 工具: 采用ASP.NET IIS 注册工具 (Aspnet_ ...
- kaleidoscope-llvm
http://kaleidoscope-llvm-tutorial-zh-cn.readthedocs.io/zh_CN/latest/chapter-1.html
- WinForm MDIParent如何防止重复打开
DI,全称是多文档界面(Multiple Document Interface),主要应用于基于图形用户界面的系统中.其目的是同时打开和显示多个文档,便于参考和编辑资料. 下面是一个WinForm M ...