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

58079b033e0332d374e6e439840bd91b.gif
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)

长一点的视频:

0857a893cc8a92dd370aaed4fda41d07.png
Python代码模拟的太阳系https://www.zhihu.com/video/1199877038029737984
视频:Python代码模拟的太阳系,包括了水星(Mercury), 金星(Venus),地球(Earth),月球(Moon),火星(Mars)

参考

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/528309.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

html还原ui,前端高度还原设计稿(字体篇)

前言:以前前端都是拿到psd设计图,需要自己用ps切图,需要自己在psd上面一个个去量设计的大小和间距,而现在一般都是要求设计师把设计稿直接上传到蓝湖上面,通过蓝湖的标注来写出前端代码!下面我就前端如何根…

计算机网络协议的特点,计算机网络传输层协议类型与特点

我们在上文中给大家简单介绍了计算机网络体系的七层结构,而今天我们就一起来了解一下,计算机网络传输层协议类型与特点。传输层涉及到两个重要的协议:UDP和TCP,本节我们重点介绍这两个协议。1、UDP协议1.1、UDP数据报格式UDP基本没…

ciaodvd数据集的简单介绍_人工智能进阶-CIFAR-10数据集介绍

CIFAR-10该数据集共有60000张彩色图像,这些图像是32*32,分为10个类,每类6000张图。这里面有50000张用于训练,构成了5个训练批,每一批10000张图;另外10000用于测试,单独构成一批。测试批的数据里…

已达成计算机的连接数最大值无法再,已达到计算机的连接数最大值,无法再同此远程计算机连接...

已达到计算机的连接数最大值,无法再同此远程计算机连接当打开文件共享时,弹出无法连接的对话框:“....已达到计算机的连接数最大值,无法再同此远程计算机连接”。对于server版的服务器系统,从未遇到过如此问题,而现在访问的服务器…

jq设置保留两位小数_如何实现python中format函数保留指定位数的小数?

我们经常说我国人口有13亿,这13亿数字是一个近似数。在我们无法精确准确得到一个数字时,会选择是它的近似数。近似数即经过四舍五入、进一法或者去尾法等方法得到的一个与原始数据相差不大的一个数。之前小编向大家介绍了在python中用用round函数保留两位…

计算机四级的英文,计算机四级考试中英文术语对照

access 访问存取通路进入achieve 实现完成acquire 获得adjacency list method 邻接表表示法adjacency matrix method 邻接矩阵表示法algorithm 算法allocate 留下分配analog 推论append 添加archive 档案归档array 数组assign 分配assume 假设assurance 确信信任ATM(asynchrono…

sap系统搭建教程_詹迟迟:如何搭建知识付费系统?知识付费系统搭建教程

​如何搭建知识付费系统?知识付费一直很火爆,在这个不确定的时代,很多人已经明确知道,学习是终身的事情,也有人在说这只是在制造焦虑,但知识付费越来越火是个明确的事实。这就有很多知识付费平台产生了&…

单价数量和总价的公式_人教版四年级数学上册单价、数量和总价之间的关系微课...

温馨提示:若有视频需付费才可打开,请您不予理会跳过看其它视频微课1微课2(点开下面链接即可查看)2020年秋季1-9年级学生课本上册全套多版本电子版都在这了部编小学语文1-6年级上册全册优质授课视频人教版数学四年级上册《大数的认识1-1:亿以内…

2038计算机系统,2038年问题

2038年问题是指在使用POSIX时间的32位计算机应用程序上,格林尼治时间2038年1月19日凌晨03:14:07(北京时间:2038年1月19日中午11:14:07)之后无法正常工作。中文名2038年问题外文名Year 2038 problem概 念计算机bug(程序错误)载 体使用POSIX时间的32…

苹果关掉200m限制_苹果下载大于200M限制

不用管它,点击好。然后按Home键(或上拉Home条)回到桌面,这时候你会看到你想下载的软件已经在桌面了,但是是灰色的,下面写着等待中,你不用理,点开 iPhone设置 -> 通用 -> 日期与时间 -> 自动设置(把…

重启计算机后桌面顺序是反的,Win10系统为什么重启电脑之后桌面上的图标排列顺序被打乱该如何处理...

导语:许多盆友发觉在应用Win10系统时,重新启动以后桌面图标越来越错乱,针对桌面图标不多的盆友而言还行,如果多的客户那简直十分烦闷的事儿,下面白豆芽就和大家分享Win10系统为什么重启电脑之后桌面上的图标排列顺序被打乱该如何处理。解决方法一:图标自…

boot lvm 分区_Linux如何在线对逻辑分区扩容

Linux如何在线对逻辑分区扩容1.前言目前绝大部分IaaS平台基本都会选择类似Vmware VsphereSAN存算分离的架构,或者选择类似Nutanix、Vmware Vsan或者深信服等存算一体的超融合架构。不管何种方式,都会遇到已挂载目录磁盘空间不足的情况,部分分…

计算机磁盘清理软件,清理磁盘空间的7种技巧,电脑装机、安装系统必备

随着技术的进行,硬盘变得越来越大,但它们似乎总是会装满。如果使用的是固态驱动器(SSD),它的空间比传统的机械硬盘要小得多,那就更是如此。如果你的硬盘空间不足,下面这些技巧可以帮助你清除硬盘上的垃圾,为…

攀爬网怎么取消_桂林旅游学院宿舍条件怎么样

大学就是我们的第二个家,高考填报志愿时,桂林旅游学院宿舍条件怎么样、好不好是广大同学和家长朋友们十分关心的问题,为了方便大家查询,大学生必备网已经为大家整理好了桂林旅游学院宿舍条件和宿舍图片,供大家参考。1、…

微信怎么绑定消息服务器吗,fastweixin: 极其方便的实现微信公众平台服务端开发,2行代码完成服务器绑定,3行代码实现用户消息监听...

fastweixin作者:peiyu快速搭建微信公众平台服务器简单封装了所有与微信服务器交互的消息:文本消息、图片消息、图文消息等等提供了基于springmvc以及基于servlet框架的控制器,集成了微信服务器绑定、监听所有类型消息的方法使用时继承,重写即可&#xff…

炒菜机器人放食材的顺序_如果给你个做饭机器人,你会让它做些什么饭菜?

我曾去过一个从事人工智能软件开发的工程师家里,进她家,从进门开锁、开灯、烧开水、泡咖啡、扫地机、蒸饭、炖汤、洗碗机等基本上实现了智能控制。我笑着说,如果再有个机器人帮你炒菜,你就实现“家务自由”了!现在唯独…

服务器中文件设置密码,共享服务器文件权限怎么设置密码

共享服务器文件权限怎么设置密码 内容精选换一换该步骤必须在root用户下执行,若以普通系统用户登录,需要执行su切换到root用户下执行后续操作。ssh-keygen -t rsa过程中需要:(可选)输入保存的文件名,默认为在/root/.ssh/id_rsa目录…

ajax定时器怎么写,js定时器怎么写?就是在特定时间执行某段程序

js定时器怎么写?就是在特定时间执行某段程序复制代码 代码如下:$(function(){var handler function(){}var timer setInterval( handler , 1000);var clear function(){clearInterval(timer);}});我要在定时里面加一个页面跳转,然后在页面load的时候加…

vue读取服务器文件跨域,新版vue-cli模板下本地开发环境使用node服务器跨域的方法...

背景我们都知道浏览器有一个既核心也最基本的安全功能,即同源策略。同源分别是:协议,域名,端口。如果浏览器访问服务器不同源的话,就会访问不到数据。那开发中常常访问的服务器不同源,那么可以借助一个服务器当做中介来…

一个账号可以登录几台机器_干货:一个PubMed账号可以有这么多用处!

且不说撰写一个综述类文章,就连平时的课题设计和汇报,都是动辄几十篇文献以上,那么,该如何管理这么多文献呢?笔者认为,一个PubMed账号足矣。我们都知道,在生物医药领域,PubMed这个文…