python:分形与数据可视化:DLA
扩散有限凝聚模型DLA
DLA模型的思想:先在一个平面方形的中心放入一个种子粒子,平面也可以是其他形状,种子粒子是静止不动的;然后在方形区域边界的某个位置上,随机释放一个新的粒子,新的粒子以随机的方式行走,当行走碰到种子粒子时,就会与静止的种子粒子凝聚成一个整体(形成一个小的凝聚体),当行走碰到区域边界时,就会消失;接着在方形区域边界的某个位置上,再随机释放一个新的粒子,新粒子同样随机行走,碰到已形成的凝聚体则凝聚,碰到区域边界则消失。重复这样的过程,会渐渐凝聚出一个越来越大的凝聚体,也就是 DLA 凝聚体(Cluster )。我们可以很容易地在计算机上模拟这个过程,释放1000 个、2000个或10000个粒子,最终会生成各种各样的分形结构。
import matplotlib.pyplot as plt
import math
import random
def distance(p1,p2):
x1=p1[0]
y1=p2[1]
x2=p2[0]
y2=p2[1]
d=math.sqrt((x1-x2)**2+(y1-y2)**2)
return d
#判断移动点是否接近凝聚体,move_dot为移动点,points为凝聚点列表
def is_near(move_dot,points):
for point in points:
if distance(move_dot,point) < 2:
return True
#判断移动点是否超出边界,move_dot为移动点
def over_boundary(move_dot):
x=move_dot[0]
y=move_dot[1]
if x<0 or x>100 or y<0 or y>100:
return True
else:
return False
#开始主程序
if __name__=='__main__':
#打开交互模式
plt.ion()
#设置背景色
bg_color=(50/255,101/255,206/255)
plt.figure(facecolor=bg_color)
plt.axes(facecolor=bg_color)
#在区域中放着种子粒子
points=[(50,50)]#points为凝聚体列表,初始只有种子粒子
plt.scatter(50,50,s=3,c='white',alpha=1)
#在区域边界释放3500个粒子
for n in range(3500):
#在区域的四条边上,随机取一个位置,释放一个粒子
r=100*random.random()
move_dot=random.choice([(0,r),(r,0),(100,r),(r,100)])
#随机生成x轴,y轴方向偏差
o_x=2*random.normalvariate(0,0.1)
o_y=2*random.normalvariate(0,0.1)
#粒子随机行走,直到接近凝聚体或碰到边界
while not over_boundary(move_dot):
if is_near(move_dot,points):#如果接近凝聚体,则与凝聚体凝聚
points.append(move_dot)
break
# 否则,继续随机行走
else:#移动到下一位置
x=move_dot[0]+o_x#o_x为负时,x轴方向向左;为正时,x轴方向向右
y=move_dot[1]+o_y#o_y为负时,y轴方向向下;为正时,y轴方向向上
move_dot=(x,y)
#如果碰到边界,则粒子消失
if over_boundary(move_dot):
continue
#清除当前的axes,即清除当前绘图区域
plt.cla()
#设置x轴y轴坐标范围
plt.xlim(0,100)
plt.ylim(0,100)
#隐藏坐标轴
plt.axis('off')
X=[p[0] for p in points]
Y=[p[1] for p in points]
plt.scatter(X,Y,s=3,c='white',alpha=1)
#暂停0.1秒
plt.pause(0.1)
#关闭交互模式
plt.ioff()
#保存图形到文件
plt.savefig('C:\\Users\\14486\\Desktop\\1.png',facecolor=(50/255,101/255,206/255))
DLA 一根线
#DLA一根线
import matplotlib.pyplot as plt
import math
import random
def distance(p1,p2):
x1=p1[0]
y1=p2[1]
x2=p2[0]
y2=p2[1]
d=math.sqrt((x1-x2)**2+(y1-y2)**2)
return d
#判断移动点是否接近x轴或凝聚体
def is_near(move_dot,points):
if move_dot[1]<2:
return True
if points:
for point in points:
if distance(move_dot,point) < 2:
return True
return False
#判断移动点是否超出边界,move_dot为移动点
def over_boundary(move_dot):
x=move_dot[0]
y=move_dot[1]
if x<0 or x>100:
return True
else:
return False
#开始主程序
if __name__=='__main__':
#打开交互模式
plt.ion()
#在区域中放着种子粒子
points=[]#points为凝聚体列表,初始为x轴
plt.scatter(50,50,s=3,c='white',alpha=1)
#在区域边界释放3500个粒子
for n in range(3500):
#在区域的四条边上,随机取一个位置,释放一个粒子
r=100*random.random()
move_dot=(r,100)
#随机生成x轴,y轴方向偏差
o_x=2*random.normalvariate(0,0.1)
o_y=2*random.normalvariate(0,0.1)
#粒子随机行走,直到接近凝聚体或碰到边界
while not over_boundary(move_dot):
if is_near(move_dot,points):#如果接近凝聚体,则与凝聚体凝聚
points.append(move_dot)
break
# 否则,继续随机行走
else:#移动到下一位置
x=move_dot[0]+o_x#o_x为负时,x轴方向向左;为正时,x轴方向向右
y=move_dot[1]+o_y#o_y为负时,y轴方向向下;为正时,y轴方向向上
move_dot=(x,y)
#如果碰到边界,则粒子消失
if over_boundary(move_dot):
continue
#清除当前的axes,即清除当前绘图区域
plt.cla()
#设置x轴y轴坐标范围
plt.xlim(0,100)
plt.ylim(0,100)
#隐藏坐标轴
plt.axis('off')
X=[p[0] for p in points]
Y=[p[1] for p in points]
plt.scatter(X,Y,s=3,c='red')
#暂停0.1秒
plt.pause(0.1)
#关闭交互模式
plt.ioff()
#保存图形到文件
plt.savefig('C:\\Users\\14486\\Desktop\\1.png',facecolor=(50/255,101/255,206/255))

浙公网安备 33010602011771号