热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

一篇文章教你用Python绘画一个太阳系

这篇文章主要给大家介绍了关于如何利用Python绘画一个太阳系,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着

你们要的3D太阳系

图片上传之后不知为何帧率降低了许多。。。

日地月三体

所谓三体,就是三个物体在重力作用下的运动。由于三点共面,所以三个质点仅在重力作用下的运动轨迹也必然无法逃离平面。

三体运动所遵循的规律就是古老而经典的万有引力

在这里插入图片描述

则对于 m i 而言,

在这里插入图片描述

在这里插入图片描述

将其写为差分形式

在这里插入图片描述

由于我们希望观察三体运动的复杂形式,而不关系其随对应的宇宙星体,所以不必考虑单位制,将其在二维平面坐标系中拆分,则

在这里插入图片描述

#后续代码主要更改这里的参数
m = [1.33e20,3.98e14,4.9e12]
x = np.array([0,1.5e11,1.5e11+3.8e8])
y = np.array([0,0,0])
u = np.array([0,0,0])
v = np.array([0,2.88e4,1.02e3])

由于地月之间的距离相对于日地距离太近,所以在画图的时候将其扩大100倍,得到图像

在这里插入图片描述

尽管存在误差,但最起码看到了地球围绕太阳转,月球围绕地球转。。。代码为

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
m = [1.33e20,3.98e14,4.9e12]
x = np.array([0,1.5e11,1.5e11+3.8e8])
y = np.array([0.0,0,0])
u = np.array([0.0,0,0])
v = np.array([0,2.88e4,2.88e4+1.02e3])
fig = plt.figure(figsize=(12,12))
ax = fig.add_subplot(xlim=(-2e11,2e11),ylim=(-2e11,2e11))
ax.grid()
trace0, = ax.plot([],[],"-", lw=0.5)
trace1, = ax.plot([],[],"-", lw=0.5)
trace2, = ax.plot([],[],"-", lw=0.5)
pt0, = ax.plot([x[0]],[y[0]] ,marker="o")
pt1, = ax.plot([x[0]],[y[0]] ,marker="o")
pt2, = ax.plot([x[0]],[y[0]] ,marker="o")
k_text = ax.text(0.05,0.85,"",transform=ax.transAxes)
textTemplate = "t = %.3f days
"
N = 1000
dt = 36000
ts =  np.arange(0,N*dt,dt)/3600/24
xs,ys = [],[]
for _ in ts:
    x_ij = (x-x.reshape(3,1))
    y_ij = (y-y.reshape(3,1))
    r_ij = np.sqrt(x_ij**2+y_ij**2)
    for i in range(3):
        for j in range(3):
            if i!=j :
                u[i] += (m[j]*x_ij[i,j]*dt/r_ij[i,j]**3)
                v[i] += (m[j]*y_ij[i,j]*dt/r_ij[i,j]**3)
    x += u*dt
    y += v*dt
    xs.append(x.tolist())
    ys.append(y.tolist())
xs = np.array(xs)
ys = np.array(ys)
def animate(n):
    trace0.set_data(xs[:n,0],ys[:n,0])
    trace1.set_data(xs[:n,1],ys[:n,1])
    #绘图时的地月距离扩大100倍,否则看不清
    tempX2S = xs[:n,1]+100*(xs[:n,2]-xs[:n,1])
    tempY2S = ys[:n,1]+100*(ys[:n,2]-ys[:n,1])
    trace2.set_data(tempX2S,tempY2S)
    pt0.set_data([xs[n,0]],[ys[n,0]])
    pt1.set_data([xs[n,1]],[ys[n,1]])
    tempX = xs[n,1]+100*(xs[n,2]-xs[n,1])
    tempY = ys[n,1]+100*(ys[n,2]-ys[n,1])
    pt2.set_data([tempX],[tempY])
    k_text.set_text(textTemplate % ts[n])
    return trace0, trace1, trace2, pt0, pt1, pt2, k_text
ani = animation.FuncAnimation(fig, animate, 
    range(N), interval=10, blit=True)
plt.show()
ani.save("3.gif")

日地火

在这里插入图片描述

m = [1.33e20,3.98e14,4.28e13]
x = np.array([0,1.5e11,2.28e11])
y = np.array([0.0,0,0])
u = np.array([0.0,0,0])
v = np.array([0,2.88e4,2.4e4])
### 由于火星离地球很远,所以不必再改变尺度
def animate(n):
    trace0.set_data(xs[:n,0],ys[:n,0])
    trace1.set_data(xs[:n,1],ys[:n,1])
    trace2.set_data(xs[:n,2],ys[:n,2])
    pt0.set_data([xs[n,0]],[ys[n,0]])
    pt1.set_data([xs[n,1]],[ys[n,1]])
    pt2.set_data([xs[n,2]],[ys[n,2]])
    k_text.set_text(textTemplate % ts[n])
    return trace0, trace1, trace2, pt0, pt1, pt2, k_text

得到

在这里插入图片描述

这个运动要比月球的运动简单得多――前提是开上帝视角,俯瞰太阳系。如果站在地球上观测火星的运动,那么这个运动可能相当带感

在这里插入图片描述

所以这都能找到规律,托勒密那帮人也真够有才的。

太阳系

由于太阳和其他星体之间的质量相差悬殊,所以太阳系内的多体运动,都将退化为二体问题,甚至如果把太阳当作不动点,那就成了单体问题了。

尽管如此,我们还是尽可能地模仿一下太阳系的运动情况

质量 半长轴(AU) 平均速度(km/s)
水星 0.055 0.387 47.89
金星 0.815 0.723 35.03
地球 1 1 29.79
火星 0.107 1.524 24.13
木星 317.8 5.203 13.06
土星 95.16 9.537 9.64
天王星 14.54 19.19 6.81
海王星 17.14 30.07 5.43
冥王星

除了水星偏心率为0.2,对黄道面倾斜为7°之外,其余行星的偏心率皆小于0.1,且对黄道面倾斜普遍小于4°。由于水星的轨道太小,偏不偏心其实都不太看得出来,所以就当它是正圆也无所谓了,最后得图

在这里插入图片描述

au,G,RE,ME = 1.48e11,6.67e-11,1.48e11,5.965e24
m = np.array([3.32e5,0.055,0.815,1,
              0.107,317.8,95.16,14.54,17.14])*ME*6.67e-11
r = np.array([0,0.387,0.723,1,1.524,5.203,
              9.537,19.19,30.7])*RE
theta = np.random.rand(9)*np.pi*2
x = r*np.cos(theta)
y = r*np.sin(theta)
v = np.array([0,47.89,35.03,29.79,
              24.13,13.06,9.64,6.81,5.43])*1000
u = -v*np.sin(theta)
v = v*np.cos(theta)
name = "solar.gif"
fig = plt.figure(figsize=(10,10))
ax = fig.add_subplot(xlim=(-31*RE,31*RE),ylim=(-31*RE,31*RE))
ax.grid()
traces = [ax.plot([],[],"-", lw=0.5)[0] for _ in range(9)]
pts = [ax.plot([],[],marker="o")[0] for _ in range(9)]
k_text = ax.text(0.05,0.85,"",transform=ax.transAxes)
textTemplate = "t = %.3f days
"
N = 500
dt = 3600*50
ts =  np.arange(0,N*dt,dt)
xs,ys = [],[]
for _ in ts:
    x_ij = (x-x.reshape(len(m),1))
    y_ij = (y-y.reshape(len(m),1))
    r_ij = np.sqrt(x_ij**2+y_ij**2)
    for i in range(len(m)):
        for j in range(len(m)):
            if i!=j :
                u[i] += (m[j]*x_ij[i,j]*dt/r_ij[i,j]**3)
                v[i] += (m[j]*y_ij[i,j]*dt/r_ij[i,j]**3)
    x += u*dt
    y += v*dt
    xs.append(x.tolist())
    ys.append(y.tolist())
xs = np.array(xs)
ys = np.array(ys)
def animate(n):
    for i in range(9):
        traces[i].set_data(xs[:n,i],ys[:n,i])
        pts[i].set_data(xs[n,i],ys[n,i])
    k_text.set_text(textTemplate % (ts[n]/3600/24))
    return traces+pts+[k_text]
ani = animation.FuncAnimation(fig, animate, 
    range(N), interval=10, blit=True)
plt.show()
ani.save(name)

由于外圈的行星轨道又长速度又慢,而内层的刚好相反,所以这个图很难兼顾,观感上也不太好看。

如果只画出木星之前的星体,顺便加上小行星带,可能会好一些。

在这里插入图片描述

通过这个图就能看出来,有一颗小行星被木星弹了过来,直冲冲地向地球赶来,幸好又被太阳弹了出去,可见小行星还是挺危险的,好在这只是个假想图。


推荐阅读
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • 本文介绍了机器学习手册中关于日期和时区操作的重要性以及其在实际应用中的作用。文章以一个故事为背景,描述了学童们面对老先生的教导时的反应,以及上官如在这个过程中的表现。同时,文章也提到了顾慎为对上官如的恨意以及他们之间的矛盾源于早年的结局。最后,文章强调了日期和时区操作在机器学习中的重要性,并指出了其在实际应用中的作用和意义。 ... [详细]
  • 本文介绍了使用cacti监控mssql 2005运行资源情况的操作步骤,包括安装必要的工具和驱动,测试mssql的连接,配置监控脚本等。通过php连接mssql来获取SQL 2005性能计算器的值,实现对mssql的监控。详细的操作步骤和代码请参考附件。 ... [详细]
  • 基于dlib的人脸68特征点提取(眨眼张嘴检测)python版本
    文章目录引言开发环境和库流程设计张嘴和闭眼的检测引言(1)利用Dlib官方训练好的模型“shape_predictor_68_face_landmarks.dat”进行68个点标定 ... [详细]
  • 图像因存在错误而无法显示 ... [详细]
  • Python使用Pillow包生成验证码图片的方法
    本文介绍了使用Python中的Pillow包生成验证码图片的方法。通过随机生成数字和符号,并添加干扰象素,生成一幅验证码图片。需要配置好Python环境,并安装Pillow库。代码实现包括导入Pillow包和随机模块,定义随机生成字母、数字和字体颜色的函数。 ... [详细]
  • Python教学练习二Python1-12练习二一、判断季节用户输入月份,判断这个月是哪个季节?3,4,5月----春 ... [详细]
  • 我用Tkinter制作了一个图形用户界面,有两个主按钮:“开始”和“停止”。请您就如何使用“停止”按钮终止“开始”按钮为以下代码调用的已运行功能提供建议 ... [详细]
  • 关于如何快速定义自己的数据集,可以参考我的前一篇文章PyTorch中快速加载自定义数据(入门)_晨曦473的博客-CSDN博客刚开始学习P ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 展开全部下面的代码是创建一个立方体Thisexamplescreatesanddisplaysasimplebox.#Thefirstlineloadstheinit_disp ... [详细]
  • 本文介绍了利用ARMA模型对平稳非白噪声序列进行建模的步骤及代码实现。首先对观察值序列进行样本自相关系数和样本偏自相关系数的计算,然后根据这些系数的性质选择适当的ARMA模型进行拟合,并估计模型中的位置参数。接着进行模型的有效性检验,如果不通过则重新选择模型再拟合,如果通过则进行模型优化。最后利用拟合模型预测序列的未来走势。文章还介绍了绘制时序图、平稳性检验、白噪声检验、确定ARMA阶数和预测未来走势的代码实现。 ... [详细]
author-avatar
a403441305
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有