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

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

  • 主流的大爆炸理论认为,宇宙大爆炸发生在138.17亿年前。
  • 约66亿年前,一颗超新星爆炸后产生了一团星云,逐渐形成了太阳系的雏形。
  • 约46亿年前,这团星云最中心的巨大氢球,开始产生聚变反应,太阳就此诞生。
  • 约45亿年前,一颗火星大小的行星“忒伊亚”撞上了地球的雏形,体积增加了近一倍,地球诞生。
  • 在这次撞击中,“忒伊亚”残骸的一部分形成了月球。
  • 太阳半径696000km,地球半径6371km,月球半径1738km,三者之比约为为400:3.67:1。
  • 太阳绕银河系中心公转周期约2.5亿年。
  • 太阳也在自转,不过因为是等离子体,所以不同纬度有不同的自转速度。赤道区域自转最快,周期为24.47天。
  • 地球自转周期为1天,公转周期为365.2564天(恒星年)或365.2422天(回归年)。
  • 地球公转轨道是一个近似圆的椭圆,长半轴为149600000km,短半轴为149580000km,曲率为0.016722。
  • 地球自转轴并不垂直于地球公转轨道面,地球公转轨道面(黄道面)与地球赤道面夹角为23.43° 。
  • 月球公转周期为27.32日(恒星月),或29.53天(朔望月),月球自转周期为27.32日(恒星月)。
  • 月球轨道面对黄道面的倾角是5.145°,月球赤道面对黄道面的倾角是1.543°,月球轨道面与月球赤道面夹角为6.688° 。
  • 月球轨道是一个椭圆,长半轴为385000km,离心率是0.0549。
  • 地球公转和自转方向、月球公转和自转方向、太阳的自转方向,是一致的,都是自西向东。

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

# -*- coding: utf-8 -*-import numpy as np
from scipy.spatial.transform import Rotation as sstr
from wxgl import wxplot as pltR_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 = av1a2, v2 = av2v1, 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, vecdef 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, zsdef 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_EARTHr = 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_EARTHr = 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_EARTHr = 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_MONTHr = 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 + d2def rotate_m(i):"""月球自转函数:T_MONTH_SELF个计数周期旋转一周"""#return (i%T_MONTH_SELF)*360/T_MONTH_SELF, (0,-np.tan(np.radians(A_M_EQUATOR)),1)return (i%T_MONTH_SELF)*360/T_MONTH_SELF, (0,0,1)# 初始化画布
plt.figure(elevation=5, azimuth=-25) # size=(1280,1080), zoom=0.45
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()

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

暑假来了,画一个日月地球的轨道模型给孩子们,秒懂四季更迭、日蚀月蚀相关推荐

  1. 程序员炫酷溜娃!用代码画地球、日月的动态轨道模型

    作者|天元浪子 来源|Python作业辅导员 无言相守45亿年,太阳.地球和月球这三个好基友究竟是怎样的关系呢?从孩提时代我就一直在想,要是能有一个可以直观演示太阳.地球和月球运行轨迹的模型就好了.今 ...

  2. python绘制太阳系模型_画一个太阳系的模型

    1 .画一个太阳系的模型? 2 .地球公转对地球有什么影响? 3 .摆在摆钟里是怎样工作的?摆在摆钟里起到了什么作用?人们为什么会选择摆作为摆钟 的控制核心?摆的快慢与那些因素有关? 4 . Xx 家 ...

  3. Directx11教程(6) 画一个简单的三角形(2)

    在上篇教程中,我们实现了在D3D11中画一个简单的三角形,但是,当我们改变窗口大小时候,三角形形状却随着窗口高宽比例改变而改变,如下图所示: 这是因为我们改变了窗口大小,但后缓冲大小在程序初始化时候, ...

  4. 用Python Turtle库画一个萌化的蜘蛛侠

    你是从什么时候开始喜欢上漫威电影的?美国队长,钢铁侠,雷神? 我先入坑的是因为看了蜘蛛侠,小时候看完就幻想着什么时候自己也能成为一个英雄,我觉得第一代蜘蛛侠刻画得是最好的,也是给我印象最深刻的一代蜘蛛 ...

  5. 使用AI画一个冠状病毒

    前言 近期有关于冠状病毒的信息很多,相关学术论文数目也在不断增加.为了让论文好看一点,今天我们来使用AI画一个冠状病毒,练习练习AI的画图技巧. 软件 Adobe Illustrator CC 201 ...

  6. 用ggplot包画一个简单饼图

    用ggplot包画一个简单饼图 首先用library函数加载ggplot2包 1 2 3 4 library(ggplot2) library(dplyr) library(tidyr) librar ...

  7. 用python画哆啦a梦的身体_用Python画一个哆啦A梦

    Python自带的turtle海龟绘图库功能十分强大,使用起来也很简单方便,今天我们就使用海龟绘图画一个我们都很喜欢的卡通形象-哆啦A梦头像.我们将整个头像分为几个部分分别定义相关的绘制函数,下面分别 ...

  8. 如何用 css 画一个心形

    如何用 css 画一个心形 (How to draw hearts using CSS) 用两个长方形切圆角倾斜位移并合并为一个心形 第一步 画一个长方形 (Draw a rectangle) 这个长 ...

  9. matlab 画一个矩形

    画一个矩形 %rectangle('Position',[x,y,w,h],'PropertyName',propertyvalue) %axis([xmin,xmax,ymin,ymax]) clc ...

最新文章

  1. 报错解决:Liquid Warning: Liquid syntax error (line 2): Expected dotdot but found id in {{(site.github.p
  2. ANT集成SVNANT访问SVN(Subversion)
  3. babel7中 preset-env 完全使用
  4. Java核心技术笔记——第 12 章 反射
  5. 第三篇:Spring Boot整合Servlet
  6. Java读带有BOM的UTF-8文件乱码原因及解决方法(转)
  7. 计算机程序设计通讯录,(定稿)通讯录c语言程序设计(喜欢就下吧)
  8. 关于AndroidStudio结合百度地图Api开发的SHA1获取
  9. 局域网管理工具_分享一款苹果手机文件管理工具
  10. python爬取拉钩网信息
  11. linux更新后不能进入系统,Ubuntu内核升级后无法进入系统的解决办法
  12. 练习题58:接口练习1:用接口、多态、方法来实现:麻雀会飞 鹦鹉会飞 鸵鸟不会飞 企鹅不会飞 直升飞机会飞
  13. FMVP詹姆斯,王者归来!英雄实至名归!
  14. 物业设备与设施管理【2】
  15. 关于网线水晶头的接法详解
  16. 镭速(Raysync)文件传输对比Filezilla测试!
  17. 建tcode維護自己創建的數據表(SE54/SM30)
  18. 在Chrome、Firefox等高版本浏览器中实现低延迟播放海康、大华RTSP
  19. 计算机存放程序和数据的设备是什么,计算机中用来存放程序和数据的部件是什么...
  20. 男主计算机 公司被抢,玄幻:开局抢了男主气运

热门文章

  1. 微信刷脸支付php后端,2.1 微信刷脸支付初始化
  2. 国税计算机专业面试题,2018年国家公务员考试:国税系统面试题
  3. K8S 1.8 平台搭建手册
  4. MyApps平台为政企数据保驾护航,筑牢办公安全防线
  5. 《python语言程序设计》第5章 课程内的笔记 中for循环转换成while
  6. 给领导敬酒杯子非要低于领导吗?
  7. 835616-60-9,4-Fluoro-thalidomide用于补充CRBN蛋白的沙利度胺基脑啡肽配体
  8. 系动词分类【大学英语笔记】
  9. python绘制多个散点图_绘制多个散点图熊猫
  10. 如何在应用中打开系统播放器