提交 99675402 编写于 作者: 三月三net's avatar 三月三net

Python超人-宇宙模拟器

上级 686226a1
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*-
# title :哈雷彗星场景模拟 # title :哈雷彗星场景半真实模拟
# description :哈雷彗星场景模拟 # description :哈雷彗星运行轨道使用了万有引力,其他天体使用 astropy 包的真实数据
# author :Python超人 # author :Python超人
# date :2023-10-25 # date :2023-10-28
# link :https://gitcode.net/pythoncr/ # link :https://gitcode.net/pythoncr/
# python_version :3.9 # python_version :3.9
# ============================================================================== # ==============================================================================
import time import math
from astropy.time import Time
from ursina import camera, application from ursina import camera, application
from bodies import Sun, Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto from bodies import Sun, Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto
from common.celestial_data_service import get_init_pos_vels, init_bodies_pos_vels from common.celestial_data_service import init_bodies_reality_pos_vels, get_reality_orbit_points, \
from common.color_utils import brightest, trail_color_brightest conv_to_astropy_time, set_solar_system_celestial_position
from common.color_utils import trail_color_brightest
from common.consts import SECONDS_PER_YEAR, AU from common.consts import SECONDS_PER_YEAR, AU
from common.func import calculate_distance from common.func import calculate_distance
from objs import HalleComet, Obj from objs import HalleComet
from sim_scenes.func import camera_look_at, two_bodies_colliding, create_text_panel from sim_scenes.func import create_text_panel
from sim_scenes.func import ursina_run, create_sphere_sky from sim_scenes.func import ursina_run, create_sphere_sky
from simulators.ursina.entities.body_timer import TimeData
from simulators.ursina.entities.entity_utils import get_value_direction_vectors
from simulators.ursina.ui.control_ui import ControlUI
from simulators.ursina.ursina_config import UrsinaConfig from simulators.ursina.ursina_config import UrsinaConfig
from simulators.ursina.ursina_event import UrsinaEvent from simulators.ursina.ursina_event import UrsinaEvent
from simulators.ursina.ursina_mesh import create_orbit_line from simulators.ursina.ursina_mesh import create_orbit_by_points, create_label
from dataclasses import dataclass
from dataclasses import field
@dataclass(order=True)
class HalleyCometParams:
start_time: str = field(default='1983-03-20 00:00:00')
init_velocity: list[float] = field(default_factory=[3.34, 0, 10.718])
init_position: list[float] = field(default_factory=[0, 0.5 * AU, -10 * AU])
class HalleyCometSim: class HalleyCometSim:
...@@ -28,21 +42,32 @@ class HalleyCometSim: ...@@ -28,21 +42,32 @@ class HalleyCometSim:
哈雷彗星场景模拟 哈雷彗星场景模拟
""" """
def __init__(self): def __init__(self, params=None):
pass if params is None:
self.params = HalleyCometParams()
else:
self.params = params
if isinstance(params.start_time, str):
self.start_time = conv_to_astropy_time(params.start_time)
else:
self.start_time = params.start_time
# print("北京时间:", dt.to_datetime(timezone=pytz.timezone('Asia/Shanghai')))
def build_solar_system(self): def build_solar_system(self):
# region 构建太阳系 # region 构建太阳系
self.sun = Sun(size_scale=0.8e2, show_trail=False) show_trail = False
self.mercury = Mercury(size_scale=5e3, show_trail=False) self.sun = Sun(size_scale=0.6e2, show_trail=show_trail)
self.venus = Venus(size_scale=5e3, show_trail=False) self.mercury = Mercury(size_scale=5e3, show_trail=show_trail)
self.earth = Earth(size_scale=5e3, rotate_angle=0, show_trail=False) self.venus = Venus(size_scale=3e3, show_trail=show_trail)
self.mars = Mars(size_scale=5e3, show_trail=False) self.earth = Earth(size_scale=3e3, rotate_angle=0, show_trail=show_trail)
self.jupiter = Jupiter(size_scale=2.5e3, show_trail=False) self.mars = Mars(size_scale=4e3, show_trail=show_trail)
self.saturn = Saturn(size_scale=2.5e3, show_trail=False) self.jupiter = Jupiter(size_scale=2.5e3, show_trail=show_trail)
self.uranus = Uranus(size_scale=6e3, show_trail=False) self.saturn = Saturn(size_scale=2.5e3, show_trail=show_trail)
self.neptune = Neptune(size_scale=6e3, show_trail=False) self.uranus = Uranus(size_scale=6e3, show_trail=show_trail)
self.pluto = Pluto(size_scale=1e5, show_trail=False) self.neptune = Neptune(size_scale=6e3, show_trail=show_trail)
self.pluto = Pluto(size_scale=1e5, show_trail=show_trail)
self.bodies = [ self.bodies = [
self.sun, # 太阳 self.sun, # 太阳
self.mercury, # 水星 self.mercury, # 水星
...@@ -53,11 +78,29 @@ class HalleyCometSim: ...@@ -53,11 +78,29 @@ class HalleyCometSim:
self.saturn, # 土星 self.saturn, # 土星
self.uranus, # 天王星 self.uranus, # 天王星
self.neptune, # 海王星 self.neptune, # 海王星
self.pluto, # 冥王星 # self.pluto, # 冥王星
] ]
self.mercury.orbital_days = 87.9691
self.venus.orbital_days = 224.701
self.earth.orbital_days = 365.24219
self.mars.orbital_days = 686.971
self.jupiter.orbital_days = 11.862 * 365.24219
self.saturn.orbital_days = 29.4571 * 365.24219
self.uranus.orbital_days = 84.0205 * 365.24219
self.neptune.orbital_days = 164.8 * 365.24219
# self.bodies = [
# self.sun, # 太阳
# self.mars, # 火星
# self.neptune, # 海王星
# ]
# endregion # endregion
trail_color_brightest(self.bodies) trail_color_brightest(self.bodies)
init_bodies_pos_vels(self.bodies) for body in self.bodies[1:]:
body.init_velocity = [0, 0, 0]
body.set_ignore_gravity(True)
init_bodies_reality_pos_vels(self.bodies, self.start_time)
def build_halley_comet(self): def build_halley_comet(self):
""" """
...@@ -66,15 +109,10 @@ class HalleyCometSim: ...@@ -66,15 +109,10 @@ class HalleyCometSim:
""" """
# 哈雷彗星的平均运行速度约为每小时 70,000 英里或每小时 126,000 公里 。(35公里/秒) # 哈雷彗星的平均运行速度约为每小时 70,000 英里或每小时 126,000 公里 。(35公里/秒)
# 每76.1年环绕太阳一周的周期彗星 # 每76.1年环绕太阳一周的周期彗星
# 3.335, 0, 10.7 73
# 3.33, 0, 10.7 73
# [3.335, 0, 10.699] 71
# [3.33, 0, 10.655] 68
# [3.33, 0, 10.66] 69
self.halley_comet = HalleComet( # size_scale=4e7, self.halley_comet = HalleComet( # size_scale=4e7,
size_scale=1e8, size_scale=0.4e8,
init_velocity=[3.34, 0, 10.7], # [3.33, 0, 10.6] < ? <[3.34, 0, 10.7] init_velocity=self.params.init_velocity,
init_position=[0, 0.5 * AU, -10 * AU]) \ init_position=self.params.init_position) \
.set_light_disable(True) .set_light_disable(True)
self.bodies.append(self.halley_comet) self.bodies.append(self.halley_comet)
...@@ -83,67 +121,159 @@ class HalleyCometSim: ...@@ -83,67 +121,159 @@ class HalleyCometSim:
self.build_solar_system() self.build_solar_system()
self.build_halley_comet() self.build_halley_comet()
def create_orbit_line(self, center_body, body):
orbital_days = int(math.ceil(body.orbital_days * 1.02))
points = get_reality_orbit_points(type(body).__name__.lower(), start_time=self.start_time, days=orbital_days,
segments=100)
# print(points)
orbit_line = create_orbit_by_points(center_body.position, points, line_color=body.trail_color)
return orbit_line
def on_ready(self): def on_ready(self):
""" """
事件绑定后,模拟器运行前会触发 事件绑定后,模拟器运行前会触发
@return: @return:
""" """
# 创建天空 # 创建天空
from ursina import scene # UrsinaConfig.trail_type = "line"
UrsinaConfig.trail_type = "line" # UrsinaConfig.trail_thickness_factor = 3
UrsinaConfig.trail_length = 91 # UrsinaConfig.trail_length = 91
UrsinaConfig.trail_thickness_factor = 3 UrsinaConfig.trail_length = 225
# camera.clip_plane_near = 0.1 # camera.clip_plane_near = 0.1
camera.clip_plane_far = 1000000 camera.clip_plane_far = 1000000
create_sphere_sky(scale=200000) create_sphere_sky(scale=200000)
# WorldGrid().draw_axises(10)
application.time_scale = 5 application.time_scale = 5
self.orbit_lines = [] self.orbit_lines = []
for body in self.bodies[1:]: for body in self.bodies[1:]:
if isinstance(body, HalleComet): if isinstance(body, HalleComet):
continue continue
print("create_orbit_line", body) orbit_line = self.create_orbit_line(self.sun, body)
orbit_line = create_orbit_line(self.sun, body)
orbit_line.body = body
self.orbit_lines.append(orbit_line) self.orbit_lines.append(orbit_line)
self.text_panel = create_text_panel() self.text_panel = create_text_panel()
def show_clock(self, dt):
"""
显示时钟
@param dt: 时间 datetime
@return:
"""
# if self.clock_position_center:
# position, origin = (0, .25), (0, 0),
# else:
position, origin = (0.60, -0.465), (-0.5, 0.5),
ControlUI.current_ui.show_message(dt.strftime('%Y-%m-%d %H:%M:%S'),
position=position,
origin=origin,
font="verdana.ttf",
close_time=-1)
def set_bodies_position(self, time_data: TimeData):
"""
设置天体的位置(包含速度和加速度的信息)
@param time_data:
@return:
"""
t = self.start_time + time_data.total_days
set_solar_system_celestial_position(self.bodies, t, False)
def create_year_label(self, trail, year, halley_comet_pos):
label = create_label(trail, label=year, pos=(0,0,0), color=(255, 255, 255), scale=40, alpha=1.0)
# label.udpate
label.set_light_off()
def on_timer_changed(self, time_data): def on_timer_changed(self, time_data):
""" """
@param time_data: @param time_data:
@return: @return:
""" """
dt = time_data.get_datetime(str(self.start_time))
year = dt.strftime("%Y")
if hasattr(self, "halley_comet"):
# 哈雷彗星飞行的翻转效果 # 哈雷彗星飞行的翻转效果
if self.halley_comet.planet.enabled: if self.halley_comet.planet.enabled:
# self.halley_comet.planet.rotation_x += 0.1 # self.halley_comet.planet.rotation_x += 0.1
# self.halley_comet.planet.rotation_y += 1 # self.halley_comet.planet.rotation_y += 1
self.halley_comet.planet.look_at(self.sun.planet) self.halley_comet.planet.look_at(self.sun.planet)
# 摄像机始终看向哈雷彗星
# camera_look_at(self.halley_comet) d_sun = calculate_distance(self.halley_comet.position, self.sun.position)
d = calculate_distance(self.halley_comet.position, self.sun.position) d_earth = calculate_distance(self.halley_comet.position, self.earth.position)
self.text_panel.text = "哈雷彗星距离太阳:%.3f AU" % (d / AU) trail_keys = self.halley_comet.planet.trails.keys()
last_trail = list(trail_keys)[-1] # self.halley_comet.planet.trails[list(trail_keys)[-1]]
if hasattr(last_trail, "entity_infos"):
# print(last_trail.entity_infos)
last_trail.entity_infos["distance_from_sun"] = d_sun
last_trail.entity_infos["distance_from_earth"] = d_earth
last_trail.entity_infos["time"] = dt.strftime("%Y-%m-%d")
# print(last_trail.entity_infos)
if not hasattr(self, "last_year"):
self.create_year_label(last_trail, year, self.halley_comet.planet.position)
elif self.last_year != year:
self.create_year_label(last_trail, year, self.halley_comet.planet.position)
self.last_year = year
panel_text = "哈雷彗星:\n距离太阳:%.3f AU" % (d_sun / AU)
panel_text += "\n距离地球:%.3f AU" % (d_earth / AU)
velocity, _ = get_value_direction_vectors(self.halley_comet.velocity)
panel_text += "\n当前速度:%.3f km/s" % velocity
self.text_panel.text = panel_text
self.set_bodies_position(time_data)
self.show_clock(dt)
for i, orbit_line in enumerate(self.orbit_lines): for i, orbit_line in enumerate(self.orbit_lines):
if i < 4: orbit_line.position = self.sun.planet.position
adj_scale = False
else: def on_body_trail_clicked(self, e):
adj_scale = True if e["key"] == "right mouse up":
# 由于天体运行不是标准的圆形,则需要动态调整轨道的大小,保证轨道线始终在天体的中心位置 trail = e["sender"]
orbit_line.auto_adjust(adj_scale=adj_scale) d_sun = trail.entity_infos["distance_from_sun"]
d_earth = trail.entity_infos["distance_from_earth"]
t = trail.entity_infos["time"]
# print("key:", e["key"])
msg = "哈雷彗星:\n距离太阳:%.3f AU" % (d_sun / AU)
msg += "\n距离地球:%.3f AU" % (d_earth / AU)
msg += "\n当前日期:[%s]" % t
ControlUI.current_ui.show_message(msg, close_time=3)
if __name__ == '__main__': if __name__ == '__main__':
""" """
哈雷彗星场景模拟 哈雷彗星场景模拟
""" """
sim = HalleyCometSim() # 近日点 0.586 AU
# 上次通过近日点: 1986年2月9日
# 下次通过近日点: 2061年7月28日
# 远日点 35.1 AU 2023年12月9日
# [3.34, 0, 10.7] 2060-4-
# [3.34, 0, 10.712] 2061-5
# [3.34, 0, 10.715] 2061-6-24
# [3.34, 0, 10.718] 2061-8
params = HalleyCometParams(
start_time='1983-03-20 00:00:00',
init_velocity=[3.34, 0, 10.718],
init_position=[0, 0.5 * AU, -10 * AU]
)
sim = HalleyCometSim(params)
sim.build() sim.build()
# 订阅事件后,上面2个函数功能才会起作用 # 订阅事件后,上面2个函数功能才会起作用
# 运行中,每时每刻都会触发 on_timer_changed # 运行中,每时每刻都会触发 on_timer_changed
UrsinaEvent.on_timer_changed_subscription(sim.on_timer_changed) UrsinaEvent.on_timer_changed_subscription(sim.on_timer_changed)
# 运行前会触发 on_ready # 运行前会触发 on_ready
UrsinaEvent.on_ready_subscription(sim.on_ready) UrsinaEvent.on_ready_subscription(sim.on_ready)
# 天体拖尾点击事件
UrsinaEvent.on_body_trail_clicked_subscription(sim.on_body_trail_clicked)
# 使用 ursina 查看的运行效果 # 使用 ursina 查看的运行效果
# 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹
# position = 左-右+、上+下-、前+后- # position = 左-右+、上+下-、前+后-
...@@ -156,5 +286,6 @@ if __name__ == '__main__': ...@@ -156,5 +286,6 @@ if __name__ == '__main__':
# bg_music='sounds/no_glory.mp3', # bg_music='sounds/no_glory.mp3',
show_camera_info=False, show_camera_info=False,
show_control_info=False, show_control_info=False,
show_timer=True, timer_enabled=True,
show_grid=False) show_grid=False
)
\ No newline at end of file
...@@ -90,9 +90,10 @@ class HalleyCometSim: ...@@ -90,9 +90,10 @@ class HalleyCometSim:
""" """
# 哈雷彗星的平均运行速度约为每小时 70,000 英里或每小时 126,000 公里 。(35公里/秒) # 哈雷彗星的平均运行速度约为每小时 70,000 英里或每小时 126,000 公里 。(35公里/秒)
# 每76.1年环绕太阳一周的周期彗星 # 每76.1年环绕太阳一周的周期彗星
self.halley_comet = HalleComet( # size_scale=4e7, self.halley_comet = HalleComet(
# size_scale=4e7,
size_scale=1e8, size_scale=1e8,
init_velocity=[3.34, 0, 10.7], init_velocity=[3.34, 0, 10.718],
init_position=[0, 0.5 * AU, -10 * AU]) \ init_position=[0, 0.5 * AU, -10 * AU]) \
.set_light_disable(True) .set_light_disable(True)
......
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*-
# title :哈雷彗星场景半真实模拟 # title :哈雷彗星场景模拟
# description :哈雷彗星运行轨道使用了万有引力,其他天体使用 astropy 包的真实数据 # description :哈雷彗星场景模拟
# author :Python超人 # author :Python超人
# date :2023-10-28 # date :2023-10-25
# link :https://gitcode.net/pythoncr/ # link :https://gitcode.net/pythoncr/
# python_version :3.9 # python_version :3.9
# ============================================================================== # ==============================================================================
import math import time
from astropy.time import Time
from ursina import camera, application from ursina import camera, application
from bodies import Sun, Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto from bodies import Sun, Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto
from common.celestial_data_service import init_bodies_reality_pos_vels, get_reality_orbit_points, \ from common.celestial_data_service import get_init_pos_vels, init_bodies_pos_vels
conv_to_astropy_time, set_solar_system_celestial_position from common.color_utils import brightest, trail_color_brightest
from common.color_utils import trail_color_brightest
from common.consts import SECONDS_PER_YEAR, AU from common.consts import SECONDS_PER_YEAR, AU
from common.func import calculate_distance from common.func import calculate_distance
from objs import HalleComet from objs import HalleComet, Obj
from sim_scenes.func import create_text_panel from sim_scenes.func import camera_look_at, two_bodies_colliding, create_text_panel
from sim_scenes.func import ursina_run, create_sphere_sky from sim_scenes.func import ursina_run, create_sphere_sky
from simulators.ursina.entities.body_timer import TimeData
from simulators.ursina.entities.entity_utils import get_value_direction_vectors
from simulators.ursina.ui.control_ui import ControlUI
from simulators.ursina.ursina_config import UrsinaConfig from simulators.ursina.ursina_config import UrsinaConfig
from simulators.ursina.ursina_event import UrsinaEvent from simulators.ursina.ursina_event import UrsinaEvent
from simulators.ursina.ursina_mesh import create_orbit_by_points, create_label from simulators.ursina.ursina_mesh import create_orbit_line
from dataclasses import dataclass
from dataclasses import field
@dataclass(order=True)
class HalleyCometParams:
start_time: str = field(default='1983-03-20 00:00:00')
init_velocity: list[float] = field(default_factory=[3.34, 0, 10.718])
init_position: list[float] = field(default_factory=[0, 0.5 * AU, -10 * AU])
class HalleyCometSim: class HalleyCometSim:
...@@ -42,32 +28,21 @@ class HalleyCometSim: ...@@ -42,32 +28,21 @@ class HalleyCometSim:
哈雷彗星场景模拟 哈雷彗星场景模拟
""" """
def __init__(self, params=None): def __init__(self):
if params is None: pass
self.params = HalleyCometParams()
else:
self.params = params
if isinstance(params.start_time, str):
self.start_time = conv_to_astropy_time(params.start_time)
else:
self.start_time = params.start_time
# print("北京时间:", dt.to_datetime(timezone=pytz.timezone('Asia/Shanghai')))
def build_solar_system(self): def build_solar_system(self):
# region 构建太阳系 # region 构建太阳系
show_trail = False self.sun = Sun(size_scale=0.8e2, show_trail=False)
self.sun = Sun(size_scale=0.6e2, show_trail=show_trail) self.mercury = Mercury(size_scale=5e3, show_trail=False)
self.mercury = Mercury(size_scale=5e3, show_trail=show_trail) self.venus = Venus(size_scale=5e3, show_trail=False)
self.venus = Venus(size_scale=3e3, show_trail=show_trail) self.earth = Earth(size_scale=5e3, rotate_angle=0, show_trail=False)
self.earth = Earth(size_scale=3e3, rotate_angle=0, show_trail=show_trail) self.mars = Mars(size_scale=5e3, show_trail=False)
self.mars = Mars(size_scale=4e3, show_trail=show_trail) self.jupiter = Jupiter(size_scale=2.5e3, show_trail=False)
self.jupiter = Jupiter(size_scale=2.5e3, show_trail=show_trail) self.saturn = Saturn(size_scale=2.5e3, show_trail=False)
self.saturn = Saturn(size_scale=2.5e3, show_trail=show_trail) self.uranus = Uranus(size_scale=6e3, show_trail=False)
self.uranus = Uranus(size_scale=6e3, show_trail=show_trail) self.neptune = Neptune(size_scale=6e3, show_trail=False)
self.neptune = Neptune(size_scale=6e3, show_trail=show_trail) self.pluto = Pluto(size_scale=1e5, show_trail=False)
self.pluto = Pluto(size_scale=1e5, show_trail=show_trail)
self.bodies = [ self.bodies = [
self.sun, # 太阳 self.sun, # 太阳
self.mercury, # 水星 self.mercury, # 水星
...@@ -78,29 +53,11 @@ class HalleyCometSim: ...@@ -78,29 +53,11 @@ class HalleyCometSim:
self.saturn, # 土星 self.saturn, # 土星
self.uranus, # 天王星 self.uranus, # 天王星
self.neptune, # 海王星 self.neptune, # 海王星
# self.pluto, # 冥王星 self.pluto, # 冥王星
] ]
self.mercury.orbital_days = 87.9691
self.venus.orbital_days = 224.701
self.earth.orbital_days = 365.24219
self.mars.orbital_days = 686.971
self.jupiter.orbital_days = 11.862 * 365.24219
self.saturn.orbital_days = 29.4571 * 365.24219
self.uranus.orbital_days = 84.0205 * 365.24219
self.neptune.orbital_days = 164.8 * 365.24219
# self.bodies = [
# self.sun, # 太阳
# self.mars, # 火星
# self.neptune, # 海王星
# ]
# endregion # endregion
trail_color_brightest(self.bodies) trail_color_brightest(self.bodies)
for body in self.bodies[1:]: init_bodies_pos_vels(self.bodies)
body.init_velocity = [0, 0, 0]
body.set_ignore_gravity(True)
init_bodies_reality_pos_vels(self.bodies, self.start_time)
def build_halley_comet(self): def build_halley_comet(self):
""" """
...@@ -110,9 +67,9 @@ class HalleyCometSim: ...@@ -110,9 +67,9 @@ class HalleyCometSim:
# 哈雷彗星的平均运行速度约为每小时 70,000 英里或每小时 126,000 公里 。(35公里/秒) # 哈雷彗星的平均运行速度约为每小时 70,000 英里或每小时 126,000 公里 。(35公里/秒)
# 每76.1年环绕太阳一周的周期彗星 # 每76.1年环绕太阳一周的周期彗星
self.halley_comet = HalleComet( # size_scale=4e7, self.halley_comet = HalleComet( # size_scale=4e7,
size_scale=0.4e8, size_scale=1e8,
init_velocity=self.params.init_velocity, init_velocity=[3.34, 0, 10.718],
init_position=self.params.init_position) \ init_position=[0, 0.5 * AU, -10 * AU]) \
.set_light_disable(True) .set_light_disable(True)
self.bodies.append(self.halley_comet) self.bodies.append(self.halley_comet)
...@@ -121,159 +78,67 @@ class HalleyCometSim: ...@@ -121,159 +78,67 @@ class HalleyCometSim:
self.build_solar_system() self.build_solar_system()
self.build_halley_comet() self.build_halley_comet()
def create_orbit_line(self, center_body, body):
orbital_days = int(math.ceil(body.orbital_days * 1.02))
points = get_reality_orbit_points(type(body).__name__.lower(), start_time=self.start_time, days=orbital_days,
segments=100)
# print(points)
orbit_line = create_orbit_by_points(center_body.position, points, line_color=body.trail_color)
return orbit_line
def on_ready(self): def on_ready(self):
""" """
事件绑定后,模拟器运行前会触发 事件绑定后,模拟器运行前会触发
@return: @return:
""" """
# 创建天空 # 创建天空
# UrsinaConfig.trail_type = "line" from ursina import scene
# UrsinaConfig.trail_thickness_factor = 3 UrsinaConfig.trail_type = "line"
# UrsinaConfig.trail_length = 91 UrsinaConfig.trail_length = 91
UrsinaConfig.trail_length = 225 UrsinaConfig.trail_thickness_factor = 3
# camera.clip_plane_near = 0.1 # camera.clip_plane_near = 0.1
camera.clip_plane_far = 1000000 camera.clip_plane_far = 1000000
create_sphere_sky(scale=200000) create_sphere_sky(scale=200000)
# WorldGrid().draw_axises(10)
application.time_scale = 5 application.time_scale = 5
self.orbit_lines = [] self.orbit_lines = []
for body in self.bodies[1:]: for body in self.bodies[1:]:
if isinstance(body, HalleComet): if isinstance(body, HalleComet):
continue continue
orbit_line = self.create_orbit_line(self.sun, body) print("create_orbit_line", body)
orbit_line = create_orbit_line(self.sun, body)
orbit_line.body = body
self.orbit_lines.append(orbit_line) self.orbit_lines.append(orbit_line)
self.text_panel = create_text_panel() self.text_panel = create_text_panel()
def show_clock(self, dt):
"""
显示时钟
@param dt: 时间 datetime
@return:
"""
# if self.clock_position_center:
# position, origin = (0, .25), (0, 0),
# else:
position, origin = (0.60, -0.465), (-0.5, 0.5),
ControlUI.current_ui.show_message(dt.strftime('%Y-%m-%d %H:%M:%S'),
position=position,
origin=origin,
font="verdana.ttf",
close_time=-1)
def set_bodies_position(self, time_data: TimeData):
"""
设置天体的位置(包含速度和加速度的信息)
@param time_data:
@return:
"""
t = self.start_time + time_data.total_days
set_solar_system_celestial_position(self.bodies, t, False)
def create_year_label(self, trail, year, halley_comet_pos):
label = create_label(trail, label=year, pos=(0,0,0), color=(255, 255, 255), scale=40, alpha=1.0)
# label.udpate
label.set_light_off()
def on_timer_changed(self, time_data): def on_timer_changed(self, time_data):
""" """
@param time_data: @param time_data:
@return: @return:
""" """
dt = time_data.get_datetime(str(self.start_time))
year = dt.strftime("%Y")
if hasattr(self, "halley_comet"):
# 哈雷彗星飞行的翻转效果 # 哈雷彗星飞行的翻转效果
if self.halley_comet.planet.enabled: if self.halley_comet.planet.enabled:
# self.halley_comet.planet.rotation_x += 0.1 # self.halley_comet.planet.rotation_x += 0.1
# self.halley_comet.planet.rotation_y += 1 # self.halley_comet.planet.rotation_y += 1
self.halley_comet.planet.look_at(self.sun.planet) self.halley_comet.planet.look_at(self.sun.planet)
# 摄像机始终看向哈雷彗星
d_sun = calculate_distance(self.halley_comet.position, self.sun.position) # camera_look_at(self.halley_comet)
d_earth = calculate_distance(self.halley_comet.position, self.earth.position) d = calculate_distance(self.halley_comet.position, self.sun.position)
trail_keys = self.halley_comet.planet.trails.keys() self.text_panel.text = "哈雷彗星距离太阳:%.3f AU" % (d / AU)
last_trail = list(trail_keys)[-1] # self.halley_comet.planet.trails[list(trail_keys)[-1]]
if hasattr(last_trail, "entity_infos"):
# print(last_trail.entity_infos)
last_trail.entity_infos["distance_from_sun"] = d_sun
last_trail.entity_infos["distance_from_earth"] = d_earth
last_trail.entity_infos["time"] = dt.strftime("%Y-%m-%d")
# print(last_trail.entity_infos)
if not hasattr(self, "last_year"):
self.create_year_label(last_trail, year, self.halley_comet.planet.position)
elif self.last_year != year:
self.create_year_label(last_trail, year, self.halley_comet.planet.position)
self.last_year = year
panel_text = "哈雷彗星:\n距离太阳:%.3f AU" % (d_sun / AU)
panel_text += "\n距离地球:%.3f AU" % (d_earth / AU)
velocity, _ = get_value_direction_vectors(self.halley_comet.velocity)
panel_text += "\n当前速度:%.3f km/s" % velocity
self.text_panel.text = panel_text
self.set_bodies_position(time_data)
self.show_clock(dt)
for i, orbit_line in enumerate(self.orbit_lines): for i, orbit_line in enumerate(self.orbit_lines):
orbit_line.position = self.sun.planet.position if i < 4:
adj_scale = False
def on_body_trail_clicked(self, e): else:
if e["key"] == "right mouse up": adj_scale = True
trail = e["sender"] # 由于天体运行不是标准的圆形,则需要动态调整轨道的大小,保证轨道线始终在天体的中心位置
d_sun = trail.entity_infos["distance_from_sun"] orbit_line.auto_adjust(adj_scale=adj_scale)
d_earth = trail.entity_infos["distance_from_earth"]
t = trail.entity_infos["time"]
# print("key:", e["key"])
msg = "哈雷彗星:\n距离太阳:%.3f AU" % (d_sun / AU)
msg += "\n距离地球:%.3f AU" % (d_earth / AU)
msg += "\n当前日期:[%s]" % t
ControlUI.current_ui.show_message(msg, close_time=3)
if __name__ == '__main__': if __name__ == '__main__':
""" """
哈雷彗星场景模拟 哈雷彗星场景模拟
""" """
# 近日点 0.586 AU sim = HalleyCometSim()
# 上次通过近日点: 1986年2月9日
# 下次通过近日点: 2061年7月28日
# 远日点 35.1 AU 2023年12月9日
# [3.34, 0, 10.7] 2060-4-
# [3.34, 0, 10.712] 2061-5
# [3.34, 0, 10.715] 2061-6-24
# [3.34, 0, 10.718] 2061-8
params = HalleyCometParams(
start_time='1983-03-20 00:00:00',
init_velocity=[3.34, 0, 10.718],
init_position=[0, 0.5 * AU, -10 * AU]
)
sim = HalleyCometSim(params)
sim.build() sim.build()
# 订阅事件后,上面2个函数功能才会起作用 # 订阅事件后,上面2个函数功能才会起作用
# 运行中,每时每刻都会触发 on_timer_changed # 运行中,每时每刻都会触发 on_timer_changed
UrsinaEvent.on_timer_changed_subscription(sim.on_timer_changed) UrsinaEvent.on_timer_changed_subscription(sim.on_timer_changed)
# 运行前会触发 on_ready # 运行前会触发 on_ready
UrsinaEvent.on_ready_subscription(sim.on_ready) UrsinaEvent.on_ready_subscription(sim.on_ready)
# 天体拖尾点击事件
UrsinaEvent.on_body_trail_clicked_subscription(sim.on_body_trail_clicked)
# 使用 ursina 查看的运行效果 # 使用 ursina 查看的运行效果
# 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹
# position = 左-右+、上+下-、前+后- # position = 左-右+、上+下-、前+后-
...@@ -286,6 +151,5 @@ if __name__ == '__main__': ...@@ -286,6 +151,5 @@ if __name__ == '__main__':
# bg_music='sounds/no_glory.mp3', # bg_music='sounds/no_glory.mp3',
show_camera_info=False, show_camera_info=False,
show_control_info=False, show_control_info=False,
timer_enabled=True, show_timer=True,
show_grid=False show_grid=False)
)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册