简单产生复杂,混沌孕育秩序
0. 引言
a. 分形 fractal
【也叫碎形】
分形是一种具有自相似性和复杂结构的几何图形。在分形结构中,无论放大多少次,局部的结构特征都与整体结构相似。这种特性在自然界中广泛存在,比如树木枝干、山脉轮廓、云的形状等。
一些常见的分形:
🔸 规则分形:理想的数学模型,自相似性是明显的。包括但不限于:科赫曲线,科赫雪花,谢尔宾斯基三角形,谢尔品斯基地毯,康托尔集,皮亚诺曲线等。
🔹 无规分形:在物理学或自然界存在的分形,自相似是近似的或统计的。包括但不限于:雪花、海岸线、海绵、叶脉和毛细血管,茱利亚集,曼德尔布罗特集合等。
b. 混沌 chaos
混沌系统是指具有高度敏感性和不确定性的动态系统,其行为在长期预测中极为复杂。混沌系统通常表现出对初始条件的敏感性(蝴蝶效应),即微小的变化可以导致完全不同的结果,而且其行为往往看似随机,但实际上是由确定的规则产生的。
一些常见的混沌系统:
洛伦兹吸引子,罗西尔系统,Henon映射,杜福尔系统,物流映射,摆的混沌,干涉系统,螺旋混沌等。
c. 分形与混沌
分形强调几何图形和自相似性的特性,而混沌系统则侧重于动态行为和时间演化的性质。
分形具有缩放对称性,在标度变换下仍具有分形整体上相似的复杂性和不规则性(即无穷层次的自相似性),在某些情况下,分形可以是混沌系统的一种表现形式,出现在其分析中,但并非所有分形都是混沌系统。
有些分形(例如:洛伦兹吸引子,曼德尔布罗特集合)展示了混沌特性,而其他一些分形(例如:康托尔集)则缺乏动态的混沌行为。
d. 分维 D
零维的点、一维的线、二维的面、三维的立体、四维的时空,然而空间维数也可以是分数,不是整数。
分维(fractional dimension) D = l o g M l o g n D=\frac{logM}{logn} D=lognlogM
图形由M个相等的部分组成,其在先行尺度上是原图形的 1 n \frac{1}{n} n1 ,则 M × ( 1 n ) D = 1 M×{(\frac{1}{n})}^D=1 M×(n1)D=1 .
比如:
谢尔品斯基地毯
D
=
l
g
3
l
g
2
≈
1.585
\begin{align} D & = \frac{lg3}{lg2} ≈ 1.585\\ \end{align}
D=lg2lg3≈1.585
科赫曲线 D = l g 4 l g 3 ≈ 1.262 \begin{align} D & = \frac{lg4}{lg3} ≈ 1.262\\ \end{align} D=lg3lg4≈1.262
二维扩散置限凝聚
D
=
1.66
∼
1.71
\begin{align} D & = 1.66 ∼ 1.71\\ \end{align}
D=1.66∼1.71
1. 常见的分形
a. 蕨菜叶分形 fern
f ( x , y ) = [ a b c d ] [ x y ] + [ e f ] = [ a x + b y + e c x + d y + f ] f(x,y) = \left[ \begin{matrix} a & b\\ c & d\\ \end{matrix} \right] \left[ \begin{matrix} x\\ y\\ \end{matrix} \right]+\left[ \begin{matrix} e\\ f\\ \end{matrix} \right]= \left[ \begin{matrix} ax+by+e\\ cx+dy+f\\ \end{matrix} \right] f(x,y)=[acbd][xy]+[ef]=[ax+by+ecx+dy+f]
ω \omega ω | a | b | c | d | e | f | p | 产生的部分 |
---|---|---|---|---|---|---|---|---|
ƒ1 | 0 | 0 | 0 | 0.16 | 0 | 0 | 0.01 | 茎 |
ƒ2 | 0.85 | 0.04 | −0.04 | 0.85 | 0 | 1.60 | 0.84 | 连续变小的小叶子 |
ƒ3 | 0.20 | −0.26 | 0.23 | 0.22 | 0 | 1.60 | 0.07 | 最大的左侧叶 |
ƒ4 | −0.15 | 0.28 | 0.26 | 0.24 | 0 | 0.44 | 0.07 | 最大的右侧叶 |
a-f 系数;p 概率因子
所有变换的概率总和等于1,以保证在随机选择时,只有一项变换会被选中。
最知名的蕨菜叶分形是Barnsley Fern.
茎:
f
1
(
x
,
y
)
=
[
0
0
0
0.16
]
[
x
y
]
+
[
0
0
]
=
[
0
0.16
y
]
f_1(x,y) = \left[ \begin{matrix} 0 & 0\\ 0 & 0.16\\ \end{matrix} \right] \left[ \begin{matrix} x\\ y\\ \end{matrix} \right]+\left[ \begin{matrix} 0\\ 0\\ \end{matrix} \right]= \left[ \begin{matrix} 0\\ 0.16y\\ \end{matrix} \right]
f1(x,y)=[0000.16][xy]+[00]=[00.16y]
连续变小的小叶子:
f
2
(
x
,
y
)
=
[
0.85
0.04
−
0.04
0.85
]
[
x
y
]
+
[
0
1.6
]
=
[
0.85
x
+
0.04
y
−
0.04
x
+
0.85
y
+
1.6
]
f_2(x,y) = \left[ \begin{matrix} 0.85 & 0.04\\ -0.04 & 0.85\\ \end{matrix} \right] \left[ \begin{matrix} x\\ y\\ \end{matrix} \right]+\left[ \begin{matrix} 0\\ 1.6\\ \end{matrix} \right]= \left[ \begin{matrix} 0.85 x + 0.04y\\ -0.04x + 0.85y + 1.6\\ \end{matrix} \right]
f2(x,y)=[0.85−0.040.040.85][xy]+[01.6]=[0.85x+0.04y−0.04x+0.85y+1.6]
最大的左侧叶:
f
3
(
x
,
y
)
=
[
0.2
−
0.26
0.23
0.22
]
[
x
y
]
+
[
0
1.6
]
=
[
0.2
x
−
0.26
y
0.23
x
+
0.22
y
+
1.6
]
f_3(x,y) = \left[ \begin{matrix} 0.2 & -0.26\\ 0.23 & 0.22\\ \end{matrix} \right] \left[ \begin{matrix} x\\ y\\ \end{matrix} \right]+\left[ \begin{matrix} 0\\ 1.6\\ \end{matrix} \right]= \left[ \begin{matrix} 0.2x - 0.26y\\ 0.23x + 0.22y + 1.6\\ \end{matrix} \right]
f3(x,y)=[0.20.23−0.260.22][xy]+[01.6]=[0.2x−0.26y0.23x+0.22y+1.6]
最大的右侧叶:
f
4
(
x
,
y
)
=
[
−
0.15
0.28
0.26
0.24
]
[
x
y
]
+
[
0
0.44
]
=
[
−
0.15
x
+
0.28
y
0.26
x
+
0.24
y
+
0.44
]
f_4(x,y) = \left[ \begin{matrix} -0.15 & 0.28\\ 0.26 & 0.24\\ \end{matrix} \right] \left[ \begin{matrix} x\\ y\\ \end{matrix} \right]+\left[ \begin{matrix} 0\\ 0.44\\ \end{matrix} \right]= \left[ \begin{matrix} -0.15x + 0.28y\\ 0.26x + 0.24y + 0.44\\ \end{matrix} \right]
f4(x,y)=[−0.150.260.280.24][xy]+[00.44]=[−0.15x+0.28y0.26x+0.24y+0.44]
通过这些参数,可以创建不同的蕨类品种,比如:变化为Thelypteridaceae fern.
ω \omega ω | a | b | c | d | e | f | p | 产生的部分 |
---|---|---|---|---|---|---|---|---|
ƒ1 | 0 | 0 | 0 | 0.25 | 0 | -0.4 | 0.02 | 茎 |
ƒ2 | 0.95 | 0.005 | −0.005 | 0.93 | -0.002 | 0.5 | 0.84 | 连续变小的小叶子 |
ƒ3 | 0.035 | −0.2 | 0.16 | 0.04 | -0.09 | 0.02 | 0.07 | 最大的左侧叶 |
ƒ4 | −0.04 | 0.2 | 0.16 | 0.04 | 0.083 | 0.12 | 0.07 | 最大的右侧叶 |
改变茎的朝向:
# 旋转点以使茎朝左
# 这里使用旋转矩阵将点旋转 180 度(在 x 轴上翻转)
points[:, 0] = -points[:, 0]
变色
b. 科赫曲线 KochCurve
turtle绘制科赫曲线:
import turtle
import threading
pens = [] # 画笔列表
iterations_list = [1, 2, 3, 4, 5, 6] # 迭代次数列表
y_positions = [-250, -150, -50, 50, 150, 250] # 各个画笔的起始y坐标
def koch_curve(t, size, iterations):
# 科赫曲线
if iterations == 0:
t.forward(size)
else:
for angle in [0, 60, -120, 60]:
t.left(angle)
koch_curve(t, size / 3, iterations - 1)
def draw_koch_curve(t, iterations):
# 绘制科赫曲线
t.pendown()
koch_curve(t, 300, iterations)
t.hideturtle()
def setup_turtles():
# 设置多个画笔
for i, iterations in enumerate(iterations_list):
t = turtle.Turtle()
t.speed(0) # 设置绘制速度为最快
t.penup()
t.goto(-150, y_positions[i]) # 设置起始位置,x 坐标固定,y 坐标变化
pens.append((t, iterations))
def draw_curve_in_thread(t, iterations):
# 在新线程中绘制科赫曲线
draw_koch_curve(t, iterations)
# 创建一个 turtle 窗口
screen = turtle.Screen()
screen.title("Multiple Koch Curves")
setup_turtles() # 设置画笔
# 创建并启动线程
threads = []
def draw_all_curves():
for t, iterations in pens:
thread = threading.Thread(target=draw_curve_in_thread, args=(t, iterations))
threads.append(thread)
thread.start()
# 等待所有线程完成
for thread in threads:
thread.join()
draw_all_curves()
turtle.done() # 保持窗口开启,直到用户关闭
RuntimeError: main thread is not in main loop
threads = []
for t, iterations in pens:
thread = threading.Thread(target=draw_curve_in_thread, args=(t, iterations))
threads.append(thread)
thread.start()
# 等待所有线程完成
for thread in threads:
thread.join()
turtle.done() # 保持窗口开启,直到用户关闭
解决办法
c. 科赫雪花 KochSnowflake
可以由科赫曲线旋转得到。
import turtle
def koch_curve(size, iterations):
# 递归绘制科赫曲线
if iterations == 0:
turtle.fd(size)
else:
for angle in [0, 60, -120, 60]:
turtle.left(angle)
koch_curve(size / 3, iterations - 1)
# 设置 turtle 窗口
turtle.setup(800, 600) # 增加高度以适应更大的布局
turtle.speed(0) # 设置为最快速度
turtle.pensize(1)
# 绘制多个不同迭代次数的科赫曲线
iterations_list = [0, 1, 2, 3, 4] # 定义要绘制的迭代次数
size = 100 # 每条曲线的长度,可以调整以适应布局
horizontal_spacing = 110 # 各个曲线间的垂直间距
# 循环绘制
for i, iterations in enumerate(iterations_list):
turtle.penup()
turtle.goto( i*horizontal_spacing -300, 250 -size / 2) # 适当的垂直间距
turtle.setheading(0) # 确保每条曲线都从水平位置开始绘制
turtle.pendown()
koch_curve(size, iterations) # 绘制科赫曲线
# 旋转并绘制相同曲线两次,形成完整的三角形
for _ in range(2):
turtle.right(120)
koch_curve(size, iterations)
turtle.hideturtle() # 隐藏 turtle
turtle.done()
上色