# -*- coding:utf-8 -*- # title :地月拉格朗日点模拟 # description :地月拉格朗日点模拟(对理想的位置进行了调整) # author :Python超人 # date :2023-05-01 # link :https://gitcode.net/pythoncr/ # python_version :3.8 # ============================================================================== import math from bodies import Earth, Moon from common.consts import SECONDS_PER_HOUR from objs import Satellite from sim_scenes.func import ursina_run, camera_look_at, create_sphere_sky from simulators.ursina.entities.body_timer import TimeData, BodyTimer from simulators.ursina.ursina_event import UrsinaEvent from simulators.ursina.ursina_mesh import create_connecting_lines # 月球绕地球的半径 R = 363104 # 创建地月 earth = Earth(init_position=[0, 0, 0], texture="earth_hd.jpg", init_velocity=[0, 0, 0], size_scale=0.8e1) # 地球放大 8 倍,地月距离保持不变 moon = Moon(init_position=[0, 0, R], # 距地距离约: 363104 至 405696 km init_velocity=[-1.054152222, 0, 0], size_scale=1.2e1) # 月球放大 12 倍,地月距离保持不变 # region 在拉格朗日点 L1, L2, L3, L4, L5 (对理想的位置进行了调整)上创建卫星 def create_satellite(name, init_position, init_velocity): """ 在 L1, L2, L3, L4, L5 创建卫星 @param name: @param init_position: @param init_velocity: @return: """ satellite = Satellite(name=name, mass=1.4e10, size_scale=3.2e3, color=(255, 200, 0), init_position=init_position, init_velocity=init_velocity, gravity_only_for=[earth, moon]) return satellite # 在 L1 位置上创建一个具有初速度的卫星 satelliteL1 = create_satellite(name=f'卫星L1', init_position=[0, 0, 308536.672], init_velocity=[-0.890136271716, 0, 0]) # 在 L2 位置上创建一个具有初速度的卫星 satelliteL2 = create_satellite(name=f'卫星L2', init_position=[0, 0, 423338.5083198447], init_velocity=[-1.24, 0, 0]) vel_L345 = 1.048 # 在 L3 位置上创建一个具有初速度的卫星 satelliteL3 = create_satellite(name=f'卫星L3', init_position=[0, 0, -364941.3043941873], init_velocity=[vel_L345, 0, 0]) # 在 L4 位置上创建一个具有初速度的卫星 satelliteL4 = create_satellite(name=f'卫星L4', init_position=[314457.2882157448, 0, 177142.46945395062], init_velocity=[-math.sin(math.pi * 30 / 180) * vel_L345, 0, math.cos(math.pi * 30 / 180) * vel_L345]) # 在 L5 位置上创建一个具有初速度的卫星 satelliteL5 = create_satellite(name=f'卫星L5', init_position=[-314457.2882157448, 0, 177142.46945395062], init_velocity=[-math.sin(math.pi * 30 / 180) * vel_L345, 0, -math.cos(math.pi * 30 / 180) * vel_L345]) # endregion if __name__ == '__main__': from ursina import camera def on_ready(): # 运行前触发 # 摄像机看向地球 camera_look_at(earth) camera.rotation_y = -90 create_sphere_sky(scale=8000) def on_timer_changed(time_data: TimeData): # 实时删除和创建连接线 from ursina import destroy if hasattr(earth, "lines"): for line in earth.lines: destroy(line) if int(time_data.total_hours) % 8 == 0: # 创建连接线(将卫星列表用线条连接起来) earth.lines = create_connecting_lines([ [satelliteL2, satelliteL3], [satelliteL4, satelliteL1], [satelliteL5, satelliteL1], [satelliteL4, satelliteL2], [satelliteL5, satelliteL2], [satelliteL4, satelliteL3], [satelliteL5, satelliteL3], ],alpha=0.5) # 订阅事件后,上面的函数功能才会起作用 # 运行前会触发 on_ready UrsinaEvent.on_ready_subscription(on_ready) # 运行中,每时每刻都会触发 on_timer_changed UrsinaEvent.on_timer_changed_subscription(on_timer_changed) # 设置计时器的最小时间单位为分钟 BodyTimer().min_unit = BodyTimer.MIN_UNIT_MINUTES bodies = [earth, moon, satelliteL1, satelliteL2, satelliteL3, satelliteL4, satelliteL5] # 使用 ursina 查看的运行效果 # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 # position = 左-右+、上+下-、前+后- ursina_run(bodies, SECONDS_PER_HOUR * 5, # position=(-300000, 1500000, -100), position=(0, 1500000, 0), show_timer=True, cosmic_bg='', # show_trail=True )