python讨论qq群:996113038
导语:
相信有很多朋友看过《三体》这部科幻小说。里面谈到过三体问题,这是一个不可预测的混沌系统。三体文明就是在这种逆境中发展,也就是因为三体问题无法解决,三体人才才会倾全文明之力攻击地球。
今天,我们就来模拟一下这个烧脑的三体问题。
首先声明一点:小编并没有能力解决三体问题,我只是将不可求解的微分方程转化为了差分方程。设置了时间的步长。假定在这个步长内,星球受到的引力的大小和方向没有变化(其实随着星球的运动,引力大小和方向肯定变化了)。当这个步长无限小的时候(无法实现),模拟的就是真实的三体运动。
代码及相关资源获取:
1:关注“python趣味爱好者”公众号,回复“ draw25”获取源代吗。
2:加入群聊:996113038。在群文件中下载源代码以及相关资料。
开发工具:
python3.6.4
相关第三方库:
numpy
matplotlib
效果演示:下面是三体运动
基本原理:
1:我们首先要设置三个星球的初始速度,初始位置,以及质量,大小,万有引力常量.......
# 万有引力常数
G = 1
设定好步长:
# 步长
t = 1
2:随后,我们计算它们之间的距离,角度。
distance12 = np.sqrt((x1-x2)**2+(y1-y2)**2) # 物体1和物体2之间的距离
distance13 = np.sqrt((x1-x3)**2+(y1-y3)**2) # 物体1和物体3之间的距离
distance23 = np.sqrt((x2-x3)**2+(y2-y3)**2) # 物体2和物体3之间的距离
3;计算每个星球受到的万有引力大小,很明显,一个星球受到的万有引力是另外两个星球对它的万有引力的合力。
我们需要先计算这个星球受到的加速度,然后分解成水平加速度和垂直加速度。在步长t=1内,假定这段时间内引力大小不变,位置不变。计算下一段步长开始时,这个星球的位置,速度
a1_2 = G*m2/distance12 # 物体2对物体1的加速度(用上万有引力公式)
a1_3 = G*m3/distance13 # 物体3对物体1的加速度
a1_x = a1_2*(x2-x1)/distance12 + a1_3*(x3-x1)/distance13 # 物体1受到的水平加速度
a1_y = a1_2*(y2-y1)/distance12 + a1_3*(y3-y1)/distance13 # 物体1受到的垂直加速度
v1_x = v1_x + a1_x*t # 物体1的速度
v1_y = v1_y + a1_y*t # 物体1的速度
x1 = x1 + v1_x*t # 物体1的水平位置
y1 = y1 + v1_y*t # 物体1的垂直位置
x1_all = np.append(x1_all, x1) # 记录轨迹
y1_all = np.append(y1_all, y1) # 记录轨迹
4:经过无限次循环,我们就得到了三体的运动轨迹,然后,我们就用matploylib把它画出来:
plt.plot(x1, y1, 'og', markersize=m1) # 默认密度相同,质量越大的,画出来的面积越大
plt.plot(x2, y2, 'or', markersize=m2)
plt.plot(x3, y3, 'ob', markersize=m3)
plt.plot(x1_all, y1_all, '-g') # 画轨迹
plt.plot(x2_all, y2_all, '-r')
plt.plot(x3_all, y3_all, '-b')
往期精选:
python小游戏“植物大战僵尸”
python爬取“科幻小说”
部分代码:
for i in range(5000): # while True: # 无限循环用这个
distance12 = np.sqrt((x1-x2)**2+(y1-y2)**2) # 物体1和物体2之间的距离
distance13 = np.sqrt((x1-x3)**2+(y1-y3)**2) # 物体1和物体3之间的距离
distance23 = np.sqrt((x2-x3)**2+(y2-y3)**2) # 物体2和物体3之间的距离
# 对物体1的计算
a1_2 = G*m2/distance12 # 物体2对物体1的加速度(用上万有引力公式)
a1_3 = G*m3/distance13 # 物体3对物体1的加速度
a1_x = a1_2*(x2-x1)/distance12 + a1_3*(x3-x1)/distance13 # 物体1受到的水平加速度
a1_y = a1_2*(y2-y1)/distance12 + a1_3*(y3-y1)/distance13 # 物体1受到的垂直加速度
v1_x = v1_x + a1_x*t # 物体1的速度
v1_y = v1_y + a1_y*t # 物体1的速度
x1 = x1 + v1_x*t # 物体1的水平位置
y1 = y1 + v1_y*t # 物体1的垂直位置
x1_all = np.append(x1_all, x1) # 记录轨迹
y1_all = np.append(y1_all, y1) # 记录轨迹
# 对物体2的计算
a2_1 = G*m1/distance12
a2_3 = G*m3/distance23
a2_x = a2_1*(x1-x2)/distance12 + a2_3*(x3-x2)/distance23
a2_y = a2_1*(y1-y2)/distance12 + a2_3*(y3-y2)/distance23
v2_x = v2_x + a2_x*t
v2_y = v2_y + a2_y*t
x2 = x2 + v2_x*t
y2 = y2 + v2_y*t
x2_all = np.append(x2_all, x2)
y2_all = np.append(y2_all, y2)
# 对物体3的计算
a3_1 = G*m1/distance13
a3_2 = G*m2/distance23
a3_x = a3_1*(x1-x3)/distance13 + a3_2*(x2-x3)/distance23
a3_y = a3_1*(y1-y3)/distance13 + a3_2*(y2-y3)/distance23
v3_x = v3_x + a3_x*t
v3_y = v3_y + a3_y*t
x3 = x3 + v3_x*t
y3 = y3 + v3_y*t
x3_all = np.append(x3_all, x3)
y3_all = np.append(y3_all, y3)
plt.plot(x1, y1, 'og', markersize=m1) # 默认密度相同,质量越大的,画出来的面积越大
plt.plot(x2, y2, 'or', markersize=m2)
plt.plot(x3, y3, 'ob', markersize=m3)
plt.plot(x1_all, y1_all, '-g') # 画轨迹
plt.plot(x2_all, y2_all, '-r')
plt.plot(x3_all, y3_all, '-b')
感谢大家观看,有钱的老板可以打赏一下小编哦!
扫描下方二维码,关注公众号
参考资料:
参考来源:https://zhuanlan.zhihu.com/p/89946622