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)的更多相关文章

  1. JavaScript图形实例:迭代函数系统生成图形

    迭代函数系统(Iterated Function System,IFS)可以用来创建分形图案,它是分形理论的重要分支,也是分形图形处理中最富生命力而且最具有广阔应用前景的领域之一.这一工作最早可以追溯 ...

  2. 混沌分形之逻辑斯蒂(Logistic)映射系统

    前几天,有个同事看到我生成的一幅逻辑斯蒂分岔图像后,问我:“这是咪咪吗?”我回答:“淫者见淫.”好吧,这里将生成几种分岔映射图形,包括逻辑斯蒂映射系统,正弦映射系统和曼德勃罗映射系统.实际上这几种图形 ...

  3. javascript学习笔记--迭代函数

    概要 这里的迭代函数指的是对数组对象的操作方法,js数组共有五个迭代函数:every.fifter.forEach.map.some. 1.every every方法,返回值为Boolean类型,tr ...

  4. Haskell 笔记(四)函数系统

    函数系统 函数式编程当然少不了函数系统啦,在教程最初的时候就有一个最简单的函数,函数系统贯穿在Haskell全部,Haskell的函数有几个重要的性质. 首先声明一下函数的参数和返回值类型 然后有一个 ...

  5. Mathematica 迭代函数

    学习Mathematica迭代函数的几个画图例子: 1.三角形沿着某一点旋转 verticse = {{0, 0}, {1, 0}, {1/2, Sqrt[3]/2}}; tri = Line[ver ...

  6. JavaScript的迭代函数与迭代函数的实现

    前言 ​ 如果对技术很自信,请直接看 实现的源码 ​ 如果想回顾一下基础,请按文章顺序阅读 说到迭代方法,最先想到的是什么?forEach还是map,迭代的方法ES5提供了5种方法 以下定义来自 Ja ...

  7. BMDP为常规的统计分析提供了大量的完备的函数系统,如:方差分析(ANOVA)、回归分析(Regression)、非参数分析(Nonparametric Analysis)、时间序列(Times Series)等等。此外,BMDP特别擅于进行出色的生存分析(Survival Analysis )。许多年来,一大批世界范围内顶级的统计学家都曾今参与过BMDP的开发工作。这不仅使得BMDP的权威性得到

        BMDP是Bio Medical Data Processing的缩写,是世界级的统计工具软件,至今已经有40多年的历史.目前在国际上与SAS.SPSS被并称为三大统计软件包.BMDP是一个大 ...

  8. 混沌分形之马丁(Martin)迭代

    我不记得从什么地方看到的这种分形图形生成方式,再到网上找竟然一时没查到任何相关资料.没关系,总之这种图形也很漂亮多变,并且其算法比较简单.只是我最后生成的图像有点瘆人,密集恐惧症患者慎入. 相关代码如 ...

  9. 文件处理,三元操作符,seek()函数,迭代函数和列表解析,reduce函数

    1.文件读取方类型 r,r+,w,x,a, r,读文件 w,写文件,文件内容全部删除,并将新内容从第一行开始赋值 x,写文件,只有文件不存在,可写,文件存在,报错 a,在文件莫问追加信息 r+,w+, ...

随机推荐

  1. python基础下的数据结构与算法之顺序表

    一.什么是顺序表: 线性表的两种基本的实现模型: 1.将表中元素顺序地存放在一大块连续的存储区里,这样实现的表称为顺序表(或连续表).在这种实现中,元素间的顺序关系由它们的存储顺序自然表示. 2.将表 ...

  2. react运行阶段

    运行中可以使用的函数componentWillReceiveProps:父组件修改属性触发,可以修改新属性,修改状态.字面意思,组件将要接收属性,这个函数触发的时机就是组件的属性将要发生改变的时候,但 ...

  3. 回忆Ajax ๑乛◡乛๑

    东西越多,记不完,也记不住,笔记是最好的记忆了. 回顾以前的ajax的写法,简单封装一个ajax. //data = { // url: "url", // method: &qu ...

  4. Regex.Split

    private static List<int> GetThemeIds(string themeList) { const string split = "!===!" ...

  5. 异步接收MSMQ消息

    在这部分,我们将使用ThreadPool 和MSMQ 进行消息收发.MSMQ 是一个分布式队列,通过MSMQ 一个应用程序可以异步地与另外一个应用程序通信. 在一个典型的场景中,我们要向维护一个队列的 ...

  6. DMA : Timer Trigger Memory-to-memory mode,

    The DMA channels can also work without being triggered by a request from a peripheral. This mode is ...

  7. sqlserver 2012 IDE中 Windows身份验证连接服务器报错 ,Login failed for user 'xxx\Administrator'. 原因: 找不到与提供的名称匹配的登录名。

    问题描述: 本地装了两个实例,一个是SQLEXPRESS,可以正常操作.但是另一个开发常用的实例MSSQLSERVER却连Windows身份验证都报错,报的错误也是很奇葩,怎么会找不到Administ ...

  8. Delphi 完全时尚手册之 Visual Style 篇 (界面不错) 转自http://blog.csdn.net/iseekcode/article/details/4733229

    这里先说说两个概念:Theme(主题)和 Visual Style .Theme 最早出现在 Microsoft Plus! for Windows 95 中,是 Windows 中 Wallpape ...

  9. Delphi XE 5,Rad Studio XE 5 官方下载(附破解),更新 Update 1,Help Update 1

    Delphi XE 5 破解,有图有真相 Embarcadero RAD Studio XE5 Update 2 v19.0.14356.6604 (等待破解中...): http://altd.em ...

  10. Android:Attribute is missing the Android namespace prefix

    今天编写XML文件时,出现了Attribute is missing the Android namespace prefix的错误,开始一直找没找出原因,后来仔细一看原来只是一个很简单的单词书写错误 ...