IFS生成分形图案
Contents
最近看到一种分形图案hexaflake,其介绍可以在wiki看到,尝试使用python来生成这个图案。
IFS
生成方法叫做IFS,迭代函数系统。IFS方法通过迭代的方式生成一系列的点(x, y),最后把这些点画出来即可。每次迭代是通过叫做IFS码表的东西,从$(x_k, y_k)$得到$(x_{k+1}, x_{k+1})$:
$$
\left[
\begin{matrix}
x_{k+1}\\
y_{k+1}\\
\end{matrix}
\right] =
\left[
\begin{matrix}
a&b\\
c&d\\
\end{matrix}
\right]
\left[
\begin{matrix}
x_{k}\\
y_{k}\\
\end{matrix}
\right]
+
\left[
\begin{matrix}
e\\
f\\
\end{matrix}
\right]
$$
其中a, b, c, d组成的矩阵作用是压缩,旋转,e, f是平移。
一些最简单的分形图案,基本上其整体和局部的关系就是压缩之后再平移。将a, b, c, d矩阵改写成如下形式,可以得到其明确的意义。
$$
\left[
\begin{matrix}
a&b\\
c&d\\
\end{matrix}
\right] =
\left[
\begin{matrix}
rcos\theta&-ssin\phi\\
rsin\theta&scos\phi\\
\end{matrix}
\right]
$$
其中$r, s$分别是x和y轴的缩放系数,$\theta$,$\phi$是x,y轴旋转的角度。
Sierpinski
Sierpinski分形是一种简单的分形,用一个简单的Sierpinski分形来介绍IFS码表怎么获得。
示意图中可以看出,每一步都做了如下操作:
- 把整体大正方形沿x, y方向缩小1/2,然后放在三个位置
- 位置一:无平移
- 位置二:y方向平移1/2
- 位置三:x方向平移1/2
IFS表用来表示三个位置用到的是概率,在一次迭代中,平移到三个位置的概率是一样的,都是1/3。那么IFS码表是
a | b | c | d | e | f | p |
---|---|---|---|---|---|---|
1/2 | 0 | 0 | 1/2 | 0 | 0 | 1/3 |
1/2 | 0 | 0 | 1/2 | 0 | 1/2 | 1/3 |
1/2 | 0 | 0 | 1/2 | 1/2 | 0 | 1/3 |
最后生成的图形是
hexaflake
同样的,根据hexaflake的图形,可以总结其迭代中的变换。
设原正六边形正对的顶点到顶点的长度l_pp是1,那么,边长是1/2,正对的边到边距离l_ee是cos(pi/6)。
首先可以看出一个大的正六边形,迭代是分成七个小正六边形,缩小的比例是1/3,无旋转。
编号1位置,向上平移了一个小六边形的边长,可以计算出边长是1/6。f=1/6
。
编号2位置,向上平移了三个小六边形的边长
编号3位置,右移1/3个l_ee
编号4位置,右移1/3个l_ee,上移1/3
…
据此可以得到IFS码表
a | b | c | d | e | f | p |
---|---|---|---|---|---|---|
1/3 | 0 | 0 | 1/3 | 0 | 1/6 | 1/7 |
1/3 | 0 | 0 | 1/3 | 0 | 1/2 | 1/7 |
1/3 | 0 | 0 | 1/3 | cos(pi/6)/3 | 0 | 1/7 |
1/3 | 0 | 0 | 1/3 | cos(pi/6)/3 | 1/3 | 1/7 |
1/3 | 0 | 0 | 1/3 | cos(pi/6)/3 | 2/3 | 1/7 |
1/3 | 0 | 0 | 1/3 | 2cos(pi/6)/3 | 1/6 | 1/7 |
1/3 | 0 | 0 | 1/3 | 2cos(pi/6)/3 | 1/2 | 1/7 |
其python代码实现是:
|
|
生成的图形是
图案中还到处可以看到koch雪花。
参考
Author lclei
LastMod 2023-12-13