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. django表单字段

    在通过django.forms.Forms创建表单字段时,其中每个字段都有一些自定义的验证逻辑和一些其他钩子 虽然表单字段的Field类主要使用在Form类中,但也可以直接实例化来使用它们,以更好的了 ...

  2. django权限管理

    当我们为应用创建一个Models, 在同步到数据库里,django默认给了三个权限 ,就是 add, change, delete权限. 首先,我们创建一个perm_test的project, 然后再 ...

  3. 分类器评估方法:精确度-召回率-F度量(precision-recall-F_measures)

    注:本文是人工智能研究网的学习笔记 Precision和Recall都能够从下面的TP,TN,FP,FN里面计算出来. 几个缩写的含义: 缩写 含义 P condition positive N co ...

  4. 【BZOJ 1430】 1430: 小猴打架 (Prufer数列)

    1430: 小猴打架 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 625  Solved: 452 Description 一开始森林里面有N只互不相 ...

  5. 牛客网某比赛 I 小乐乐学博弈 博弈论

    题目大意: 有两堆石子\(n\)和\(m\),每次可以拿\(1 \sim k\)个 \(k >= |n - m|\) 问先手必胜? 把限制条件去掉才有意思 首先考虑两堆相等,那么先手怎么操作,后 ...

  6. BZOJ.4180.字符串计数(后缀自动机 二分 矩阵快速幂/倍增Floyd)

    题目链接 先考虑 假设S确定,使构造S操作次数最小的方案应是:对T建SAM,S在SAM上匹配,如果有S的转移就转移,否则操作数++,回到根节点继续匹配S.即每次操作一定是一次极大匹配. 简单证明:假设 ...

  7. Codeforces Round #396 (Div. 2) B. Mahmoud and a Triangle 贪心

    B. Mahmoud and a Triangle 题目连接: http://codeforces.com/contest/766/problem/B Description Mahmoud has ...

  8. 使用CefSharp在.Net程序中嵌入Chrome浏览器(三)——基本操作

    CefSharp本身提供了WPF和WinForm两个版本的控件,这两个版本的控件使用方法大同小异,由于我WPF的版本用的较多,这里就简单的介绍下WPF版的CEFSharp控件的用法. 加载页面: Ch ...

  9. Both - Either - Neither English Grammar

    http://www.grammar.cl/english/both-either-neither.htm Both, Either, Neither Summary Chart We use bot ...

  10. 未能加载文件或程序集“System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”或它的某一个依赖项

    在发布网站时遇到如题错误. 错误消息详细信息:未能加载文件或程序集“System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=3 ...