在本文仅在平面上考虑线性随机IFS迭代.
在二维平面上, 我们有如下的仿射变换:
( x ′ y ′ ) = ( a b c d ) ( x y ) + ( e f ) \begin{pmatrix} x^\prime\\y^\prime \end{pmatrix} =\begin{pmatrix} a&b\\c&d \end{pmatrix} \begin{pmatrix} x\\y \end{pmatrix}+ \begin{pmatrix} e\\f \end{pmatrix} (x′y′)=(acbd)(xy)+(ef)
对于一个比较复杂的图形, 可能需要多个不同的仿射变换来实现, 仿射变换族 { ω n } \{\omega_n\} {ωn}控制着图形的结构和形状, 由于仿射变换的形式是相同的, 所以不同的形状取决于仿射变换的系数. 另外, 仿射变换族 { ω n } \{\omega_n\} {ωn}中, 每一个仿射变换被调用的概率不一定是等同的, 也就是说, 落入图形各部分中点的数目不一定相同, 这就需要引进一个新的量, 即仿射变换 ω \omega ω被调用的概率 P P P. 从而, 6个仿射变换系数 { a , b , c , d , e , f } \{a,b,c,d,e,f\} {a,b,c,d,e,f}和一个概率 P P P便组成了线性随机IFS迭代最关键的部分——IFS码.
给定一个IFS码, 我们便可以进行多次迭代, 最终生成所需的图形.
线性随机IFS迭代法可描述如下:
首先预处理如下:
#include
#include
#include
#include
using namespace arma;
using namespace std;
再实现线性随机IFS迭代:
/*
* 线性随机IFS迭代
* ifs : IFS码
* n : 迭代次数
* x0 : 迭代初值
* path: 迭代过程保存路径
* e : 实数比较精度
*
* 返回(bool):
* true : 迭代失败
* false: 迭代成功
*/
bool IFS_iteration(const mat &ifs, unsigned n, const char *path, vec x0 = randu(2), const double &e = 1e-6)
{
if (ifs.n_cols != 7 || x0.n_elem != 2)
return true;
if (!n)
return true;
vec p = cumsum(ifs.col(6));
if (abs(p.at(p.n_elem - 1) - 1.) > e)
return true;
FILE *file;
if (fopen_s(&file, path, "w"))
return true;
fprintf(file, "x,y\n%f,%f", x0.at(0), x0.at(1));
static default_random_engine engine(time(nullptr));
static uniform_real_distribution<double> distribution;
do
{
double d(distribution(engine));
unsigned i(0);
while (p.at(i) <= d)
if (++i == p.n_elem)
{
--i;
break;
}
d = ifs.at(i, 0) * x0.at(0) + ifs.at(i, 1) * x0.at(1) + ifs.at(i, 4);
x0.at(1) = ifs.at(i, 2) * x0.at(0) + ifs.at(i, 3) * x0.at(1) + ifs.at(i, 5);
x0.at(0) = d;
fprintf(file, "\n%f,%f", x0.at(0), x0.at(1));
} while (--n);
fclose(file);
return false;
}
已知某树木的IFS码如下所示:
A = ( 0.06 0 0 0.6 0 0 0.1 0.04 0 0 − 0.5 0 1 0.1 0.46 0.32 − 0.34 0.38 0 0.6 0.1 0.48 − 0.15 0.17 0.42 0 1 0.23 0.43 0.37 − 0.26 0.48 0 1 0.23 0.42 − 0.36 0.35 0.31 0 0.8 0.24 ) A=\begin{pmatrix} 0.06&0&0&0.6&0&0&0.1\\ 0.04&0&0&-0.5&0&1&0.1\\ 0.46&0.32&-0.34&0.38&0&0.6&0.1\\ 0.48&-0.15&0.17&0.42&0&1&0.23\\ 0.43&0.37&-0.26&0.48&0&1&0.23\\ 0.42&-0.36&0.35&0.31&0&0.8&0.24 \end{pmatrix} A=⎝⎜⎜⎜⎜⎜⎜⎛0.060.040.460.480.430.42000.32−0.150.37−0.3600−0.340.17−0.260.350.6−0.50.380.420.480.31000000010.6110.80.10.10.10.230.230.24⎠⎟⎟⎟⎟⎟⎟⎞