全球首个 用代码画地球、日月的动态轨道模型

简介: 本文介绍了太阳、地球和月球之间的关系,并详细展示了如何利用WxGL绘制三者的动态轨道模型。内容涵盖天体的起源、大小、运行轨迹及关键数据,帮助读者直观理解四季变化、日月食等自然现象。通过代码实现,模型可演示天体运动规律,适合科普与教学应用。

无言相守45亿年,太阳、地球和月球这三个好基友究竟是怎样的关系呢?从孩提时代我就一直在想,要是能有一个可以直观演示太阳、地球和月球运行轨迹的模型就好了。今天,我终于实现了小时候的梦想:用WxGL画出了太阳、地球和月球的动态轨道模型。配上简单的解说,小朋友也可以秒懂四季更迭、日蚀月蚀、黄赤交角。

在开始绘制模型前,让我们先来了解一下太阳、地球和月球的起源,以及它们的大小、远近和行踪路线。

1、主流的大爆炸理论认为,宇宙大爆炸发生在138.17亿年前。

2、约66亿年前,一颗超新星爆炸后产生了一团星云,逐渐形成了太阳系的雏形。

3、约46亿年前,这团星云最中心的巨大氢球,开始产生聚变反应,太阳就此诞生。

4、约45亿年前,一颗火星大小的行星“忒伊亚”撞上了地球的雏形,体积增加了近一倍,地球诞生。

5、在这次撞击中,“忒伊亚”残骸的一部分形成了月球。

6、太阳半径696000km,地球半径6371km,月球半径1738km,三者之比约为400:3.67:1。

7、太阳绕银河系中心公转周期约2.5亿年。

8、太阳也在自转,不过因为是等离子体,所以不同纬度有不同的自转速度。赤道区域自转最快,周期为24.47天。

9、地球自转周期为1天,公转周期为365.2564天(恒星年)或365.2422天(回归年)。

10、地球公转轨道是一个近似圆的椭圆,长半轴为149600000km,短半轴为149580000km,曲率为0.016722。

11、地球自转轴并不垂直于地球公转轨道面,地球公转轨道面(黄道面)与地球赤道面夹角为23.43° 。

12、月球公转周期为27.32日(恒星月)或29.53天(朔望月),月球自转周期为27.32日(恒星月)。

13、月球轨道面对黄道面的倾角是5.145°,月球赤道面对黄道面的倾角是1.543°,月球轨道面与月球赤道面夹角为6.688° 。

14、月球轨道是一个椭圆,长半轴为385000km,离心率是0.0549。

15、地球公转和自转方向、月球公转和自转方向、太阳的自转方向,是一致的,都是自西向东。

了解了这些,就可以开始绘制模型了。关于WxGL模块的安装,请参考我近期的文章,这里不再赘述。下面是完整的代码,大约一百余行

代码语言:javascript

代码运行次数:0

运行

AI代码解释

# -*- coding: utf-8 -*-
import numpy as np
from scipy.spatial.transform import Rotation as sstr
from wxgl import wxplot as plt
R_SUN = 1                           # 以太阳半径696000km为1个单位
R_EARTH = 30 * 6371/696000          # 地球半径6371km,此处放大30倍
R_MONTH = 50 * 1738/696000          # 月球半径1738km,此处放大50倍
A_EARTH = (149600000/696000)/100    # 地球公转轨道长半轴149600000km,此处缩小100倍
E_EARTH = 0.016722                  # 地球公转轨道离心率
A_MONTH = 385000/696000             # 月球公转轨道长半轴385000km
E_MONTH = 0.0549                    # 月球公转轨道离心率
T = 36                              # 每天36个计数周期
T_SUN_SELF = int(24.47 * T)         # 太阳自转周期24.47天
T_EARTH_SELF = 1 * T                # 地球自转周期1天
T_MONTH_SELF = int(27.32 * T)       # 月球自转周期27.32天
T_EARTH = int(365.2564/3 * T)       # 地球公转周期365.2564天,此处取1/3
T_MONTH = int(27.32 * T)            # 月球公转周期27.32天
A_E_ORBIT = 23.43                   # 地球轨道面与地球赤道面夹角
A_M_ORBIT = 23.43 + 5.145           # 月球轨道面与地球赤道面夹角
A_M_EQUATOR = 23.43 - 1.543         # 月球赤道面与地球赤道面夹角
# 地球轨道倾角旋转器
ROTATOR_E_ORBIT = sstr.from_euler('xyz', (0, -A_E_ORBIT, 0), degrees=True)
# 月球轨道倾角旋转器
ROTATOR_M_ORBIT = sstr.from_euler('xyz', (0, -A_M_ORBIT, 0), degrees=True)
def rotate_merge(av1, av2):
    """将两个轴角旋转合并为一个
    av1         - 元组,首元素(浮点型)为旋转角度(逆时针为正,右手定则),尾元素(列表或元组)为旋转向量
    av2         - 元组,首元素(浮点型)为旋转角度(逆时针为正,右手定则),尾元素(列表或元组)为旋转向量
    """
    a1, v1 = av1
    a2, v2 = av2
    v1, v2 = np.array(v1), np.array(v2)
    r1 = sstr.from_rotvec(np.radians(a1)*v1/np.linalg.norm(v1))
    r2 = sstr.from_rotvec(np.radians(a2)*v2/np.linalg.norm(v2))
    m = np.dot(r1.as_matrix(), r2.as_matrix())
    r = sstr.from_matrix(m)
    vec = r.as_rotvec()
    phi = np.degrees(np.linalg.norm(vec))
    return phi, vec
def get_ellipse_orbit(a, e, n):
    """计算椭圆轨道,a为长半轴, e为离心率,n为轨道点数"""
    t = np.linspace(0, 2*np.pi, n)
    r = a*(1-e*e)/(1-e*np.cos(t))
    xs = r*np.cos(t)
    ys = r*np.sin(t)
    zs = np.zeros(r.shape)
    return xs, ys, zs
def rotate_s(i):
    """太阳自转函数:沿Z轴旋转,T_SUN_SELF个计数周期旋转一周"""
    return (i%T_SUN_SELF)*360/T_SUN_SELF, (0,0,1)
def rotate_e_orbit(i):
    """地球轨道旋转函数:沿y轴旋转23.43°(黄赤夹角)"""
    return -A_E_ORBIT, (0,1,0)
def rotate_e(i):
    """地球自转函数:沿z轴旋转,T_EARTH_SELF个计数周期旋转一周"""
    return (i%T_EARTH_SELF)*360/T_EARTH_SELF, (0,0,1)
def translate_e(i):
    """地球位移函数:T_EARTH个计数周期循环一次"""
    phi = (i%T_EARTH)*2*np.pi/T_EARTH
    r = A_EARTH*(1-E_EARTH*E_EARTH)/(1-E_EARTH*np.cos(phi))
    d = np.array((r*np.sin(phi), -r*np.cos(phi), 0))
    return ROTATOR_E_ORBIT.apply(d)
def rotate_m_orbit(i):
    """月球轨道旋转函数:沿y轴旋转28.575°后再跟随月球自转"""
    av1 = -A_M_ORBIT, (0,1,0)
    av2 = (i%T_MONTH_SELF)*360/T_MONTH_SELF, (0,0,1)
    return rotate_merge(av1, av2)
def translate_m_orbit(i):
    """月球轨道位移函数:T_EARTH个计数周期循环一次"""
    phi = (i%T_EARTH)*2*np.pi/T_EARTH
    r = A_EARTH*(1-E_EARTH*E_EARTH)/(1-E_EARTH*np.cos(phi))
    d = np.array((r*np.sin(phi), -r*np.cos(phi), 0))
    return ROTATOR_E_ORBIT.apply(d)
def translate_m(i):
    """月球位移函数:T_EARTH个计数周期循环一次"""
    phi = (i%T_EARTH)*2*np.pi/T_EARTH
    r = A_EARTH*(1-E_EARTH*E_EARTH)/(1-E_EARTH*np.cos(phi))
    d1 = np.array((r*np.sin(phi), -r*np.cos(phi), 0))
    d1 = ROTATOR_E_ORBIT.apply(d1)
    phi = (i%T_MONTH)*2*np.pi/T_MONTH
    r = A_MONTH*(1-E_MONTH*E_MONTH)/(1-E_MONTH*np.cos(phi))
    d2 = np.array((r*np.sin(phi), -r*np.cos(phi), 0))
    d2 = ROTATOR_M_ORBIT.apply(d2)
    return d1 + d2
def rotate_m(i):
    """月球自转函数:T_MONTH_SELF个计数周期旋转一周"""
    return (i%T_MONTH_SELF)*360/T_MONTH_SELF, (0,0,1)
# 初始化画布
plt.figure(elevation=5, azimuth=-25)
plt.axis(grid=False)
# 绘制太阳及其自转轴
plt.sphere((0,0,0), R_SUN, texture='res/sun.jpg', rotate=rotate_s, order='R', light=0)
plt.plot((0,0), (0,0), (1.5,-1.5), color='red', style='dash-dot')
# 绘制地球公转轨道
xs_e, ys_e, zs_e = get_ellipse_orbit(A_EARTH, E_EARTH, T_EARTH)
plt.plot(xs_e, ys_e, zs_e, color='cyan', width=1, rotate=rotate_e_orbit, order='R')
# 标注冬夏至和春秋分点
i_summer, i_winter = np.argmin(xs_e), np.argmax(xs_e)
i_autumn, i_spring = np.argmin(ys_e), np.argmax(ys_e)
plt.text('夏至', size=32, pos=ROTATOR_E_ORBIT.apply((xs_e[i_summer], ys_e[i_summer], zs_e[i_summer])))
plt.text('冬至', size=32, pos=ROTATOR_E_ORBIT.apply((xs_e[i_winter], ys_e[i_winter], zs_e[i_winter])))
plt.text('春分', size=32, pos=ROTATOR_E_ORBIT.apply((xs_e[i_spring], ys_e[i_spring], zs_e[i_spring])))
plt.text('秋分', size=32, pos=ROTATOR_E_ORBIT.apply((xs_e[i_autumn], ys_e[i_autumn], zs_e[i_autumn])))
# 绘制地球及其自转轴
plt.sphere((0,0,0), R_EARTH, texture='res/earth.jpg', rotate=rotate_e, translate=translate_e, order='TR', light=0)
plt.plot((0,0), (0,0), (0.5,-0.5), color='cyan', style='dash-dot', rotate=rotate_e, translate=translate_e, order='TR')
# 绘制月球公转轨道
xs_m, ys_m, zs_m = get_ellipse_orbit(A_MONTH, E_MONTH, T_MONTH)
plt.plot(xs_m, ys_m, zs_m, color='magenta', width=1, rotate=rotate_m_orbit, translate=translate_m_orbit, order='TR')
# 绘制月球及其自转轴
plt.sphere((0,0,0), 0.1, texture='res/month.jpg', rotate=rotate_m, translate=translate_m, order='TR', light=0)
plt.plot((0,0), (0,0), (0.3,-0.3), color='magenta', style='dash-dot', rotate=rotate_m, translate=translate_m, order='TR')
plt.show()

代码中用到了太阳、地球和月球的纹理图片,读者可自行下载或替换为自己喜欢的图片。


代码语言:javascript

代码运行次数:0

运行

AI代码解释

更多精彩推荐GitHub 遭抵制!AI 代码生成神器竟成“抄袭工具”?
基于 Python 的 8 种常用抽样方法
太酷了,Python 制作足球可视化图表 | 代码干货
相关文章
|
前端开发 中间件
ThinkPHP6.0处理前端请求跨域问题AllowCrossDomain
ThinkPHP6.0处理前端请求跨域问题AllowCrossDomain
853 0
|
Ubuntu 编译器
Ubuntu18.4下交叉编译X264和FFMPEG到ARM平台(aarch64-linux-gcc)
Ubuntu18.4下交叉编译X264和FFMPEG到ARM平台(aarch64-linux-gcc)
2566 0
|
存储 JSON 分布式计算
MongoDB【部署 01】mongodb最新版本6.0.5安装部署配置使用及mongodb-shell1.8.0安装使用(云盘分享安装文件)
MongoDB【部署 01】mongodb最新版本6.0.5安装部署配置使用及mongodb-shell1.8.0安装使用(云盘分享安装文件)
1059 0
|
人工智能 搜索推荐 API
蚂蚁百宝箱联手深铁打造全国首个地铁 AI 智能体「深铁宝」:你的全能城市向导来啦~
蚂蚁百宝箱联合深铁集团、深圳通推出全国首个“公共出行+城市服务”AI智能体「深铁宝」,上线于深圳地铁、深圳通及支付宝APP,实现一句话直达、秒级响应的智慧出行体验,涵盖出行规划、乘车码快捷调取、周边生活服务推荐等一站式功能,助力城市交通与服务数字化升级。
989 0
蚂蚁百宝箱联手深铁打造全国首个地铁 AI 智能体「深铁宝」:你的全能城市向导来啦~
|
11月前
|
存储 人工智能 编译器
智驾大模型的「隐形战场」:当GPU堆不动了,行业拼什么?
与参会嘉宾一起探讨了如何通过技术协作加速智能驾驶的进步,分享了各自在自动驾驶技术栈中的前沿实践与生态思考。
|
机器学习/深度学习 人工智能 物联网
MiniMind:2小时训练出你的专属AI!开源轻量级语言模型,个人GPU轻松搞定
MiniMind 是一个开源的超小型语言模型项目,帮助开发者以极低成本从零开始训练自己的语言模型,最小版本仅需25.8M参数,适合在普通个人GPU上快速训练。
3573 10
MiniMind:2小时训练出你的专属AI!开源轻量级语言模型,个人GPU轻松搞定
|
数据采集 机器学习/深度学习 Python
【Python】已完美解决:ImportError: cannot import name ‘Imputer‘ from ‘sklearn.preprocessing
【Python】已完美解决:ImportError: cannot import name ‘Imputer‘ from ‘sklearn.preprocessing
1482 3
|
人工智能 弹性计算 自然语言处理
【限时福利】计算巢平台热门AI服务免费试用,零门槛体验AI创新力量!
计算巢平台推出热门AI服务免费试用活动,集成大模型、图像生成、自然语言处理等多种AI技术,提供免费GPU算力与存储资源,助力开发者零门槛体验前沿技术,加速创新落地。
513 0
|
存储 SQL 关系型数据库
【赵渝强老师】使用mysqldump备份MySQL
本文介绍了 MySQL 自带的逻辑备份工具 mysqldump 的使用方法。通过 mysqldump,可以将数据库中的数据转换为对应的 SQL 插入语句,便于备份和还原。文章详细说明了如何备份所有数据库、指定数据库及特定表,排除某些表不备份的操作,以及删除数据库后如何通过备份文件恢复数据。同时提供了视频讲解和具体命令示例,帮助用户更好地理解和应用该工具。
1467 5
|
Web App开发 编解码 算法
怎么实现实时无延迟的体育电竞动画直播
实时无延迟动画直播需关注技术方案、实现步骤与专业解决方案。技术上可选WebRTC(低至100-500ms延迟,互动性强)、低延迟HLS/CMAF(1-3秒延迟,兼容性好)和RTMP(传统协议,2-5秒延迟)。实现步骤包括采集端设置(高性能编码、稳定网络)、传输优化(CDN节点选择、抗丢包协议)及播放端优化(低延迟模式、自适应码率)。专业方案有云服务(AWS、Azure、阿里云)和专用平台(Millicast、Wowza)。注意完全无延迟不可行,需权衡画质与稳定性,并考虑终端兼容性和成本。代码示例展示了比赛数据处理逻辑,涉及匹配ID、状态、计划与关注等功能。
900 11