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. rabbitmq学习(九) —— 关于消息队列的选型

    转自http://cmsblogs.com/?p=3846 在IM这种讲究高并发.高消息吞吐的互联网场景下,MQ消息中间件是个很重要的基础设施,它在IM系统的服务端架构中担当消息中转.消息削峰.消息交 ...

  2. php版本CKEditor 4和CKFinder安装及配置

    下载并解压CKEditor 4和CKFinder CKEditor 4下载地址:https://ckeditor.com/cke4/builder,选择自定义的版本,记得加上中文语言包 CKFinde ...

  3. Bzoj4558:分类讨论 计算几何 组合数学

    国际惯例的题面: 这题让我爆肝啦......这种计数显然容斥,正好不含任何坏点的我们不会算,但是我们能算至少含零个坏点的,至少含一个坏点的,至少含两个坏点的......所以最终的答案就是(至少含零个坏 ...

  4. 《linux/unix设计思想》读后感

    <linux/unix设计思想>这本书,觉得书的大部分内容都闲扯的太远了,以下简单的总结下本书的核心,帮助大家节省时间和金钱. linux/unix设计思想: 1) 程序应该小而专一,程序 ...

  5. Codeforces Round #373 (Div. 2) B. Anatoly and Cockroaches 水题

    B. Anatoly and Cockroaches 题目连接: http://codeforces.com/contest/719/problem/B Description Anatoly liv ...

  6. 使用 IntraWeb (9) - JavaScript

    IW 依赖 js 构建(我数了数, 在当前版本它的资源文件默认携带了 26 个 js); 但 IW 尽可能地让用户少用或不用 js, 但如果你对 js 也不陌生, IW 提供了多种途径与方便. 我给它 ...

  7. Ubuntu Java7 SDK环境变量配置(转)

    1.去甲骨文官网下载java7 sdk http://www.oracle.com/technetwork/java/javase/downloads/index.html 这里笔者下载了最新的jav ...

  8. Revit API遍历全部风管,找到与风管相关的墙开洞

    涉及向量计算,求相交等相关技术. )                 {                     foreach (Face face in solid.Faces)          ...

  9. .NET基于Eleasticsearch搭建日志系统实战演练

    一.需求背景介绍 1.1.需求描述 大家都知道C/S架构模式的客户端应用程序(比如:WinForm桌面应用.WPF.移动App应用程序.控制台应用程序.Windows服务等等)的日志记录都存储在本地客 ...

  10. delphi 游戏

    http://www.cnblogs.com/devlyn/archive/2010/08/24/1807190.html