zoukankan      html  css  js  c++  java
  • python的matplotlib的模拟太阳-地球-月亮运动

    #---第1步---导出模块---
    import numpy as np
    import matplotlib as mpl
    from matplotlib import pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
    import matplotlib.animation as animmation
    #导出通用字体设置
    from matplotlib import font_manager 
    #定义引出字体模块、位置、大小
    my_font = font_manager.FontProperties(fname="hwfs.ttf",size=20)
    
    #---第2步---初始化定义---
    #r1的大小与月球的速度和距离地球距离有关,越大越不好,建议10
    r1 = 10
    #r2是月球与地球的半径大小
    r2 = 2
    #π=圆周率(Pai)是圆的周长与直径的比值
    #omega1=2π是一个圆,是地球的运动一圈;1×π=为半圆。
    omega1 = 2 * np.pi
    #定义omega2为几个π,与月球的公转速度有关
    #建议24π=代表月球以地球公转的一圈分12部分,12+12半圈
    #比如48π=24+24半圈,即将地球绕太阳一圈在分24部分,月球自转和公转的速度也加快
    omega2 = 48 * np.pi
    #月球自转和公转的角度与地球公转的水平夹角
    phi = 5 * np.pi / 180 
    
    #---第3步---更新函数定义---
    def update(data):
        #声明为全局变量
        global line1, line2 , line3
        #地球公转运动的更新
        line1.set_data([data[0], data[1]])
        line1.set_3d_properties(data[2])
        #月球运动更新
        line2.set_data([data[3], data[4]])
        line2.set_3d_properties(data[5])
        #月球自转线的更新
        line3.set_data([data[6], data[7]])
        line3.set_3d_properties(data[8])
        return line1,line2,line3,
    
    #---第4步---初始化框架---
    def init():
        global line1, line2, line3
        ti = 0
        t = t_drange[np.mod(ti, t_dlen)]
        xt1 = x0 + 2*r1 * np.cos(omega1 * t)
        yt1 = y0 + 2*r1 * np.sin(omega1 * t)
        zt1 = z0 + 0
        xt2 = xt1 + 2*r2 * np.sin(omega2 * t)
        yt2 = yt1 + 2*r2 * np.cos(omega2 * t)/(np.cos(phi) * (1 + np.tan(phi) ** 2))
        zt2 = zt1 + (yt2 - yt1) * np.tan(phi)
        xt21 = xt1 + r2 * np.sin(2 * np.pi * t_range)
        yt21 = yt1 + r2 * np.cos(2 * np.pi * t_range)/(np.cos(phi) * (1 + np.tan(phi) ** 2))
        zt21 = zt1 + (yt21 - yt1) * np.tan(phi)
    
        #地球位置、形状、颜色、大小设置
        line1, = ax.plot([xt1], [yt1], [zt1], marker='o', color='blue',markersize=20)
        #月球位置、形状、颜色、大小设置
        line2, = ax.plot([xt2], [yt2], [zt2], marker='o', color='orange',markersize=12)
        #月球绕地球的轨迹线和颜色purple=紫色
        line3, = ax.plot(xt21, yt21, zt21, color='purple')
        return line1,line2,line3,
    
    #---第5步---运动数据的产生---
    def data_gen():
        global x0,y0,z0,t_dlen
        data = []
        for ti in range(1,t_dlen):
            t = t_drange[ti]
            xt1 = x0 + r1 * np.cos(omega1 * t)
            yt1 = y0 + r1 * np.sin(omega1 * t)
            zt1 = z0
            xt2 = xt1 + r2 * np.sin(omega2 * t)
            yt2 = yt1 + r2 * np.cos(omega2 * t)/(np.cos(phi) * (1 + np.tan(phi) ** 2))
            zt2 = zt1 + (yt2 - yt1) * np.tan(phi)
            xt21 = xt1 + r2 * np.sin(2 * np.pi * t_range)
            yt21 = yt1 + r2 * np.cos(2 * np.pi * t_range)/(np.cos(phi) * (1 + np.tan(phi) ** 2))
            zt21 = zt1 + (yt21 - yt1) * np.tan(phi)
            data.append([xt1, yt1, zt1, xt2, yt2, zt2, xt21, yt21, zt21])
        return data
    
    #---第6步---定义取值范围0~10,每个0.005取
    #地球公转的轨迹线刻度,越小越好,建议0.005,否则轨迹线不是圆形,有锯齿样类圆形
    t_range = np.arange(0, 10 + 0.005, 0.005)
    #地球公转速度,越大速度越大,建议0.005,
    t_drange = np.arange(0,10, 0.005 )
    t_len = len(t_range)
    t_dlen = len(t_drange)
    
    #---第7步---三大星球的大小、颜色、坐标---
    #太阳的坐标位置,三维坐标
    x0 =y0=z0= 0
    
    #地球的运动中的坐标
    x1 = x0  + r1 * np.cos(omega1 * t_range)
    y1 = y0 + r1 * np.sin(omega1 * t_range)
    z1 = z0 + np.zeros(t_len)
    
    #---第8步---定义图片f和ax等---
    #窗口大小也就是展示图片的画布大小:22=2200,14=1400,即2200×1400
    #这是窗口的背景颜色,有区别,默认白色
    f = plt.figure(figsize=(22,14),facecolor='black',edgecolor='white')
    #这是画布的背景颜色,默认白色
    ax  = f.add_subplot(111,projection='3d',facecolor='black')
    
    #---第9步---太阳和地球轨迹线设置---
    #太阳的设置颜色,位置,大小
    ax.plot([0], [0], [0], marker='o', color= 'red', markersize=100)
    #地球公转的轨迹线和颜色g=green=绿色,三维坐标
    ax.plot(x1, y1, z1, 'g')
    
    #---第10步---图片的坐标刻度设置---
    #坐标轴刻度虽然不显示,但刻度的标记对整个图形有一定的拉伸影响
    #x坐标轴刻度范围
    ax.set_xlim([-(r1 + 2), (r1 + 2)])
    #y坐标轴刻度范围
    ax.set_ylim([-(r1 + 5), (r1 + 5)])
    #z坐标轴刻度范围
    ax.set_zlim([-15, 15])
    
    #---第11步---图片标题等设置---
    #图示的标题
    #动画走起,f图片挂起动画里,不断更新,interval = 20=数值越小,速度越快
    ani = animmation.FuncAnimation(f, update, frames = data_gen(), init_func = init,interval = 20)
    #坐标及其刻度隐藏
    plt.axis('off')
    #图片标题、字体、颜色
    plt.title(u'太阳-地球-月亮模拟示意图', fontproperties=my_font,color='r')
    #图片展现
    plt.show()
  • 相关阅读:
    欧拉回路 定理
    UESTC 1087 【二分查找】
    POJ 3159 【朴素的差分约束】
    ZOJ 1232 【灵活运用FLOYD】 【图DP】
    POJ 3013 【需要一点点思维...】【乘法分配率】
    POJ 2502 【思维是朴素的最短路 卡输入和建图】
    POJ 2240 【这题貌似可以直接FLOYD 屌丝用SPFA通过枚举找正权值环 顺便学了下map】
    POJ 1860【求解是否存在权值为正的环 屌丝做的第一道权值需要计算的题 想喊一声SPFA万岁】
    POJ 1797 【一种叫做最大生成树的很有趣的贪心】【也可以用dij的变形思想~】
    js 实现slider封装
  • 原文地址:https://www.cnblogs.com/ysysbky/p/12565716.html
Copyright © 2011-2022 走看看