用python模拟三体运动_怎么用Python写一个三体的气候模拟程序

首先声明一下,这个所谓的三体气候模拟程序还是很简单的,没有真的3D效果或数学模型之类的,只不过是一个文字表示的模拟程序。该程序的某些地方可能不太严谨,所以也请各位多多包涵。

所谓三体气候模拟,就是将太阳出现的情况进行分类讨论,然后将其呈现出来。比如说一颗太阳就是恒纪元,两颗太阳可能是二日凌空或二日连珠,三颗太阳也可能是三日凌空或三日连珠。只要明白了这一点,这个三体气候模拟的程序就很好写了。

在写程序前,得先导入一个库。由于三体问题的复杂性,我们姑且将三颗太阳出现的概率定位三分之一,也就是说要用到随机的方法。所以我们这里需要导入random库中的randint——随机数函数。

from random import randint

在插入完random库后,要先确定几个变量。由于三体世界有三颗太阳,且可能出现在不同的位置,所以姑且定义变量:

#其中0代表该太阳为飞星,1代表该太阳出现

sun1 = randint(0, 1)

sun2= randint(0, 1)

sun3= randint(0, 1)#1~3分别代表不同的位置,如果位置相同就是连珠

sun1_pos = randint(1, 3)

sun2_pos= randint(1, 3)

sun3_pos= randint(1, 3)

除了这几个基础变量,还需要两个用来输出气候类型和纪元类型的变量:weather和era_mode

weather = ""era_mode= ""

因为后面将这两个变量以文字形式输出,所以是String的形式

完成变量设定后,就该考虑三体世界的气候情况了。

依照书中的描述,我们可以分为(恒纪元就不讨论了):三颗飞星(即没有太阳)、二日凌空、二日连珠、三日凌空和三日连珠

这么一来,就可以开始写程序了。

首先是没有太阳,即三颗飞星情况:

if sun1 == sun2 == sun3 == 0: #三颗太阳都没有出现

weather = "三颗飞星"era_mode= "乱纪元"

print(era_mode, weather) #输出气候情况

然后检测是否为恒纪元,即一颗太阳:

if sun1 == 1 and sun2 == sun3 ==0:

era_mode= "恒纪元"

print(era_mode)elif sun2 == 1 and sun1 == sun3 ==0:

era_mode= "恒纪元"

print(era_mode)elif sun3 == 1 and sun1 == sun2 ==0:

era_mode= "恒纪元"

print(era_mode)

接着是三颗太阳的情况:

if sun1 == sun2 == sun3 == 1:if sun1_pos == sun2_pos ==sun3_pos:

weather= "三日连珠"era_mode= "乱纪元"

print(era_mode, weather)else:

weather= "三日凌空"era_mode= "乱纪元"

print(era_mode, weather)

最后是两颗太阳的情况,就相对比较麻烦了:

if sun1 == sun2 == 1:if sun1_pos ==sun2_pos:

weather= "二日连珠"era_mode= "乱纪元"

print(era_mode, weather)else:

weather= "二日凌空"era_mode= "乱纪元"

print(era_mode, weather)elif sun1 == sun3 == 1:if sun1_pos ==sun2_pos:

weather= "二日连珠"era_mode= "乱纪元"

print(era_mode, weather)else:

weather= "二日凌空"era_mode= "乱纪元"

print(era_mode, weather)elif sun2 == sun3 == 1:if sun2_pos ==sun3_pos:

weather= "二日连珠"era_mode= "乱纪元"

print(era_mode, weather)else:

weather= "二日凌空"era_mode= "乱纪元"

print(era_mode, weather)

注意,这个从三颗飞星、一颗太阳、三颗太阳、两颗太阳的顺序是不能打乱的,否则就会出现气候判断不准的情况,因为这个程序的运行是从上往下走的,是线性的。举个例子,如果现在有三颗太阳,而两颗太阳的判定在三颗太阳的判定之前,程序运行时就会出现只输出二日连珠或二日凌空的情况,而不会输出三日凌空或三日连珠。

当然,你也可以用其他的方法让气候判断的排序改变,比如可以全部把这些判断啥的写道不同的函数里在进行判断,但在这里就不加以赘述。

最后把全部代码放上来:

1 from random importrandint2

3 #其中0代表该太阳为飞星,1代表该太阳出现

4 sun1 = randint(0, 1)5 sun2 = randint(0, 1)6 sun3 = randint(0, 1)7 #1~3分别代表不同的位置,如果位置相同就是连珠

8 sun1_pos = randint(1, 3)9 sun2_pos = randint(1, 3)10 sun3_pos = randint(1, 3)11

12 weather = ""

13 era_mode = ""

14

15 if sun1 == sun2 == sun3 == 0: #三颗太阳都没有出现

16 weather = "三颗飞星"

17 era_mode = "乱纪元"

18 print(era_mode, weather) #输出气候情况

19 elif sun1 == 1 and sun2 == sun3 ==0:20 era_mode = "恒纪元"

21 print(era_mode)22 elif sun2 == 1 and sun1 == sun3 ==0:23 era_mode = "恒纪元"

24 print(era_mode)25 elif sun3 == 1 and sun1 == sun2 ==0:26 era_mode = "恒纪元"

27 print(era_mode)28 elif sun1 == sun2 == sun3 == 1:29 if sun1_pos == sun2_pos ==sun3_pos:30 weather = "三日连珠"

31 era_mode = "乱纪元"

32 print(era_mode, weather)33 else:34 weather = "三日凌空"

35 era_mode = "乱纪元"

36 print(era_mode, weather)37 elif sun1 == sun2 == 1:38 if sun1_pos ==sun2_pos:39 weather = "二日连珠"

40 era_mode = "乱纪元"

41 print(era_mode, weather)42 else:43 weather = "二日凌空"

44 era_mode = "乱纪元"

45 print(era_mode, weather)46 elif sun1 == sun3 == 1:47 if sun1_pos ==sun2_pos:48 weather = "二日连珠"

49 era_mode = "乱纪元"

50 print(era_mode, weather)51 else:52 weather = "二日凌空"

53 era_mode = "乱纪元"

54 print(era_mode, weather)55 elif sun2 == sun3 == 1:56 if sun2_pos ==sun3_pos:57 weather = "二日连珠"

58 era_mode = "乱纪元"

59 print(era_mode, weather)60 else:61 weather = "二日凌空"

62 era_mode = "乱纪元"

63 print(era_mode, weather)

总行数不超过100行,还是挺精简的

如果要查看太阳的生成,可以在添加完变量后(即上述代码的11行处)添加:

print("sun1: %u , sun2: %u , sun3: %u" %(sun1, sun2, sun3))print("sun1_pos: %u , sun2_pos: %u , sun3: %u" % (sun1_pos, sun2_pos, sun3_pos))

欸嘿?你问我print里输入%是什么意思?python3 语法小记可以帮到你,毕竟这个语法还是蛮重要的,可以免去在print中加逗号所带来的一格空格。

2020/3/3

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
三体问题是指三个天体之间相互作用的问题,可以用牛顿万有引力定律来描述。为了模拟三体问题,我们需要定义每个天体的质量、初始位置和速度,并使用数值积分方法来计算它们的运动轨迹。以下是一个使用 Python 模拟三体问题的示例代码: ```python import numpy as np import matplotlib.pyplot as plt # 定义天体质量、初始位置和速度 m1, m2, m3 = 1, 1, 1 G = 1 r1 = np.array([-0.5, 0, 0]) r2 = np.array([0.5, 0, 0]) r3 = np.array([0, 1, 0]) v1 = np.array([0.5, 0.5, 0]) v2 = np.array([-0.5, -0.5, 0]) v3 = np.array([0, 0, 0]) # 定义运动方程 def f(r): x1, y1, z1, x2, y2, z2, x3, y3, z3 = r r12 = np.sqrt((x1 - x2)**2 + (y1 - y2)**2 + (z1 - z2)**2) r13 = np.sqrt((x1 - x3)**2 + (y1 - y3)**2 + (z1 - z3)**2) r23 = np.sqrt((x2 - x3)**2 + (y2 - y3)**2 + (z2 - z3)**2) ax1 = G * m2 * (x2 - x1) / r12**3 + G * m3 * (x3 - x1) / r13**3 ay1 = G * m2 * (y2 - y1) / r12**3 + G * m3 * (y3 - y1) / r13**3 az1 = G * m2 * (z2 - z1) / r12**3 + G * m3 * (z3 - z1) / r13**3 ax2 = G * m1 * (x1 - x2) / r12**3 + G * m3 * (x3 - x2) / r23**3 ay2 = G * m1 * (y1 - y2) / r12**3 + G * m3 * (y3 - y2) / r23**3 az2 = G * m1 * (z1 - z2) / r12**3 + G * m3 * (z3 - z2) / r23**3 ax3 = G * m1 * (x1 - x3) / r13**3 + G * m2 * (x2 - x3) / r23**3 ay3 = G * m1 * (y1 - y3) / r13**3 + G * m2 * (y2 - y3) / r23**3 az3 = G * m1 * (z1 - z3) / r13**3 + G * m2 * (z2 - z3) / r23**3 return np.array([v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], v3[0], v3[1], v3[2], ax1, ay1, az1, ax2, ay2, az2, ax3, ay3, az3]) # 使用 Runge-Kutta 数值积分方法计算运动轨迹 r = np.array([r1[0], r1[1], r1[2], r2[0], r2[1], r2[2], r3[0], r3[1], r3[2], v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], v3[0], v3[1], v3[2]]) dt = 0.01 t = np.arange(0, 100, dt) x1, y1, z1, x2, y2, z2, x3, y3, z3 = np.zeros((9, len(t))) for i in range(len(t)): x1[i], y1[i], z1[i], x2[i], y2[i], z2[i], x3[i], y3[i], z3[i], vx1, vy1, vz1, vx2, vy2, vz2, vx3, vy3, vz3 = r k1 = dt * f(r) k2 = dt * f(r + 0.5 * k1) k3 = dt * f(r + 0.5 * k2) k4 = dt * f(r + k3) r += (k1 + 2 * k2 + 2 * k3 + k4) / 6 # 绘制运动轨迹 fig = plt.figure() ax = fig.add_subplot(111, projection='3d') ax.plot(x1, y1, z1, label='Body 1') ax.plot(x2, y2, z2, label='Body 2') ax.plot(x3, y3, z3, label='Body 3') ax.set_xlabel('X') ax.set_ylabel('Y') ax.set_zlabel('Z') ax.legend() plt.show() ``` 在上述代码中,我们使用了 Runge-Kutta 数值积分方法来计算天体的运动轨迹。具体来说,我们将运动方程表示为 $f(r)$,其中 $r$ 是一个包含位置和速度的向量,然后使用 Runge-Kutta 方法迭代计算 $r$ 的值。最后,我们使用 Matplotlib 库绘制了三个天体的运动轨迹。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值