Python代码模拟的太阳系,包括了水星(Mercury), 金星(Venus),地球(Earth),月球(Moon),火星(Mars)

上面的动画是我用86行Python代码模拟的一个比较真实的太阳系,用到的基本原理就是N体问题,这是计算天体物理里面的一个重要问题和方法。计算天体物理是用计算机来模拟宇宙中的天体和天文现象,从而对它们进行科学研究。真正用于科研的模拟程序大多是非常复杂的,有着上万行甚至更多代码。这里我写了一个非常简短的代码模拟太阳系行星的运动轨迹,目的只是为了好玩以及展现一下计算天体物理的奇妙之处。

我们知道,行星沿着主要由太阳引力决定的轨道运动。要计算行星的轨道,我们需要计算来自太阳的引力并将其积分以获得速度和位置。我们在高中的时候学过牛顿万有引力定律和牛顿运动定律:

然后通过下面的公式来演化行星的位置和速度:

这里用的是欧拉积分法的一个改进方法--反向欧拉法。这个方法不同于欧拉法的是,它是稳定的,所以行星的轨道是闭合的。这个方法既简单又比较精确性。

上面的三个向量方程可以写成分量形式:

用Python编程的一个好处就是Python可以很优雅地处理向量,不同于C/C++。上面的九个方程式(三个向量方程式,每个具有三个分量)可以很容易地用三行代码实现:

p.r += p.v * dt
acc = -2.959e-4 * p.r / np.sum(p.r**2)**(3./2)  # in units of AU/day^2
p.v += acc * dt

现在我们可以演化行星的轨道了,我们还缺的是初始条件,也就是某个时间所有行星的位置和速度。我没有用随意假设的初始条件去做一个艺术性的动画,而是从NASA的JPL实验室的Horizons程序里调用太阳系的数据[1],获取一个时刻的行星的精确位置和速度作为模拟的初始条件

from astroquery.jplhorizons import Horizons
obj = Horizons(id=1, location="@sun", epochs=Time("2017-01-01").jd, id_type='id').vectors()

其中 id=1 代表水星(2代表金星,依此类推)。然后 obj['x'] 就是水星在2017年1月1日的x坐标。

程序计算了4个内行星(水星、金星、地球和火星)加上月球在2019年和2020年的轨道。对应的现实世界的时间显示在左上角。这个时间段可以在代码的前两行随意设置。

将上面这些内容放在一起,再加上一些 matplotlib 的 animation 动画包和其他一些设置,就完成了全部的代码。完整的代码在文章的最后。

这个模拟哪些是真实的,哪些是不真实的?

程序计算的所有星体的位置和速度是准确的,当然会存在一些模型和算法上的误差,比如没有考虑行星之间的引力。星体的大小不是真实的比例,不然就什么也看不见了,但这它们的相对大小是对的。也是这个原因,月球(小黄点)才会出现在地球的上部。另外,程序的计算是3维的,动画显示的只是在地球轨道平面的投影。如果你感兴趣的话,画面地球轨道的最左边对应的是春分,也就是3月21日,然后最下边是夏至。一般太阳系的坐标系是这样定义的。

程序是实时计算行星轨迹,还是从互联网调用数据然后做成动画?

是实时计算的。初始条件是用的网上的数据。

为什么水星的轨迹这么丑?

呃,它就是这么丑,我有什么办法。水星跟太阳系中其他所有行星不同,它的轨道的偏心率很高,高达0.2,意思就是它的轨道不是很圆。

可以做成3D动画吗?

2D的就足够了吧,因为行星基本都在同一个平面上。我估计写成3D的也不是非常复杂,大概可以把代码控制在100行以内。如果很多人有兴趣的话,我以后可能会更新一次。

为什么只有4个行星?

因为从第5颗行星木星开始,轨道半径变得非常大(大于地球的5倍)。加上它们的话,就几乎看不见地球了。

最后附上代码。下载请去GitHub:https://github.com/chongchonghe/Python-solar-system

#!/usr/bin/env python
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from astropy.time import Time
from astroquery.jplhorizons import Horizonssim_start_date = "2019-01-01"     # simulating a solar system starting from this date
sim_duration = 2 * 365                # (int) simulation duration in days
m_earth = 5.9722e24 / 1.98847e30  # Mass of Earth relative to mass of the sun
m_moon = 7.3477e22 / 1.98847e30class Object:def __init__(self, name, rad, color, r, v):self.name = nameself.r    = np.array(r, dtype=np.float)self.v    = np.array(v, dtype=np.float)self.xs = []self.ys = []self.plot = ax.scatter(r[0], r[1], color=color, s=rad**2, edgecolors=None, zorder=10)self.line, = ax.plot([], [], color=color, linewidth=1.4)class SolarSystem:def __init__(self, thesun):self.thesun = thesunself.planets = []self.time = Noneself.timestamp = ax.text(.03, .94, 'Date: ', color='w', transform=ax.transAxes, fontsize='x-large')def add_planet(self, planet):self.planets.append(planet)def evolve(self):dt = 1.0self.time += dtplots = []lines = []for i2, p in enumerate(self.planets):p.r += p.v * dtacc = -2.959e-4 * p.r / np.sum(p.r**2)**(3./2)  # in units of AU/day^2if p.name == 399:         # Force from the Moon to Earthdr = p.r - self.planets[3].r  # trick here, assuming moon is the 4th objectacc += -2.959e-4 * m_moon * dr / np.sum(dr**2)**(3./2)if p.name == 301:         # Force from earth to the Moondr = p.r - self.planets[2].racc += -2.959e-4 * m_earth * dr / np.sum(dr**2)**(3./2)p.v += acc * dtp.xs.append(p.r[0])p.ys.append(p.r[1])p.plot.set_offsets(p.r[:2])plots.append(p.plot)if i2 != 3:          # ignore trajectory lines of the Moonp.line.set_xdata(p.xs)p.line.set_ydata(p.ys)lines.append(p.line)if len(p.xs) > 10000:raise SystemExit("Stopping after a long run to prevent memory overflow")self.timestamp.set_text('Date: ' + Time(self.time, format='jd', out_subfmt='date').iso)return plots + lines + [self.timestamp]plt.style.use('dark_background')
fig = plt.figure(figsize=[6, 6])
ax = plt.axes([0., 0., 1., 1.], xlim=(-1.8, 1.8), ylim=(-1.8, 1.8))
ax.set_aspect('equal')
ax.axis('off')
ss = SolarSystem(Object("Sun", 28, 'red', [0, 0, 0], [0, 0, 0]))
ss.time = Time(sim_start_date).jd
colors = ['gray', 'orange', 'blue', 'yellow', 'chocolate']
sizes = [0.38, 0.95, 1., 0.27, 0.53]
names = ['Mercury', 'Venus', 'Earth-Moon', 'Earth-Moon', 'Mars']
for i, nasaid in enumerate([1, 2, 399, 301, 4]):obj = Horizons(id=nasaid, location="@sun", epochs=ss.time, id_type='id').vectors()ss.add_planet(Object(nasaid, 20 * sizes[i], colors[i], [np.double(obj[xi]) for xi in ['x', 'y', 'z']], [np.double(obj[vxi]) for vxi in ['vx', 'vy', 'vz']]))ax.text(0, - ([.47, .73, 1, 1.02, 1.5][i] + 0.1),names[2] if i in [2, 3] else names[i], color=colors[i], zorder=1000,ha='center', fontsize='large')
def animate(i):return ss.evolve()
ani = animation.FuncAnimation(fig, animate, repeat=False, # init_func=init,frames=sim_duration, blit=True, interval=20,)
plt.show()
# ani.save('solar_system_6in_200dpi.mp4', fps=40, dpi=200)

长一点的视频:

Python代码模拟的太阳系https://www.zhihu.com/video/1199877038029737984

视频:Python代码模拟的太阳系,包括了水星(Mercury), 金星(Venus),地球(Earth),月球(Moon),火星(Mars)

参考

  1. ^https://ssd.jpl.nasa.gov/?horizons

python一百行代码多少钱_用86行Python代码模拟太阳系相关推荐

  1. 转行python能拿到多少钱_想转行学python过来人提醒大家几点

    因为目前python非常火,应用也非常广泛,是目前最火的行业之一,竞争很大,工资很高,未来发展也极好. Python 现在到底有多热呢?我觉得我们可以看以下的这2组数据. 第一:Python 排名稳居 ...

  2. python docx 加粗的边框_修改固定行与列的加粗边框显示样式

    Spreadfor ASP.NET 6.0产品中提供了固定行与固定列的功能,用户只需设置以下两行代码就可以实现: this.FpSpread1.Sheets[0].FrozenRowCount = 2 ...

  3. python自动化工具哪个好用_微软最强 Python 自动化工具开源了!不用写一行代码!...

    本文转自"AirPython" 1. 前言 最近,微软开源了一款非常强大的 Python 自动化依赖库:playwright-python 它支持主流的浏览器,包含:Chrome. ...

  4. python做一个网页多少钱_网站建设平台_ 网站建设多少钱_ _做一个企业网站需要多少钱_64岁的Python之父表示退休后太无聊 正式加入微软...

    按照TIOBE发布的2020年11月编程语言排行版,Python首次高出了Java成为全球第二受接待的编程语言.近些年,跟着人工智能的飞速成长,Python已成为最受接待的编程语言之一.作为Pytho ...

  5. 用python对人口模型数据拟合_万字案例 | 用Python建立客户流失预测模型(含源数据+代码)...

    1.采集数据 本数据集来自DF ,数据源地址: https://www.datafountain.cn/dataSets/35/details# 本数据集描述了电信用户是否流失以及其相关信息,共包含7 ...

  6. 利用python爬取知乎评论_一个简单的python爬虫,爬取知乎

    一个简单的python爬虫,爬取知乎 主要实现 爬取一个收藏夹 里 所有问题答案下的 图片 文字信息暂未收录,可自行实现,比图片更简单 具体代码里有详细注释,请自行阅读 项目源码: 1 # -*- c ...

  7. python量化分析系列(第一篇)_量化分析师的 Python 日记 [第 1 天:谁来给我讲讲 Python?]...

    45 条回复 • 2016-05-25 11:10:23 +08:00 1 2015-04-08 21:42:42 +08:00 这里竟然有Quant 2 2015-04-08 22:49:51 +0 ...

  8. 编写python程序一年365天_编写第一个Python程序

    无论读者使用的是哪种操作系统,相信都已经安装好了 Python 环境,可以通过命令行窗口或者 Python 自带的 IDLE 成功启动交互式解释器(如图所示). 本节将带领读者正式编写第一个 Pyth ...

  9. python结合c语言能干啥_第9p,Python是什么?学了Python能干什么?

    大家好,我是杨数Tos,这是<从零基础到大神>系列课程的第9篇文章,第二阶段的课程:Python基础知识之Python语言介绍 学习本课程,建议先学习:[计算机基础知识]课程 一.Pyth ...

最新文章

  1. 十天快速入门Python
  2. 《Redis官方文档》 FAQ
  3. SD-WAN将成为物联网部署中的骨干网—Vecloud
  4. jQuery学习笔记2
  5. C/C++指针和取地址操作
  6. jsp里照片放在哪里_2020年初级会计报名照片怎么上传?
  7. python 如何通过海表面高度数据计算海表地转流速、并绘制流线图
  8. 安装光盘并重新启动计算机戴尔,戴尔电脑怎么设置光盘启动
  9. java hl7v3_hl7 java 解析
  10. 第一章概述-------第一节--1.1计算机网络在信息时代中的作用
  11. 带你理解JS中的Events事件
  12. java poi生成word 并插入 表格
  13. 云锁和安全狗哪个好 Bypass阿里云盾、百度云加速、安全宝、安全狗、云锁、360主机卫士SQL注入防御-系统/上网/安全
  14. Adobe XMP SDK项目应用(续2)
  15. ACS运动控制:ACSPL+ 总结
  16. SLM27211 4A 120V 一款国产的NMOS驱动器 兼容 UCC27211 NCP81075 商用的电源解决方案
  17. Oralce数据库备份与恢复
  18. java程序员微信群,欢迎准java行业人员加入,会一直更新
  19. 福大软工 · 最终作业 - 软件工程实践总结(个人)
  20. Axure 真正的解决跳转事件无效

热门文章

  1. 关于低代码真实技术趋势,听低代码巨头 Mendix 怎么说
  2. NVIDIA发布先进的软件定义自主机器平台DRIVE AGX Orin
  3. 「2019 嵌入式智能国际大会」 399 元超值学生票来啦,帮你豪省 2600 元!
  4. 华为表示年内没有推出搭载鸿蒙操作系统手机的计划;OpenStack或被抛弃?iPhone至少还要三年可苹果自研5G调制解调器……...
  5. 华为正准备发布属于自己的手机操作系统;腾讯已经交出了首张产业互联网成绩单……...
  6. 云存储精华问答 | 云存储的优势在哪?
  7. ftp4j jar maven依赖_maven系列--maven添加第三方、本地依赖
  8. Linux图片马PHP,php 根据请求生成缩略图片保存到Linux图片服务器的代码
  9. ETL异构数据源Datax_工具部署_02
  10. Flowable 数据库表结构 ACT_HI_COMMENT