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

Python超人-宇宙模拟器

上级 f13243c5
...@@ -13,4 +13,5 @@ from objs.sci_fi_bomber import SciFiBomber ...@@ -13,4 +13,5 @@ from objs.sci_fi_bomber import SciFiBomber
from objs.water_drop import WaterDrop from objs.water_drop import WaterDrop
from objs.sci_fi_gunship import ScifiGunship from objs.sci_fi_gunship import ScifiGunship
from objs.halley_comet import HalleComet from objs.halley_comet import HalleComet
from objs.camera_target import CameraTarget
# -*- coding:utf-8 -*-
# title :摄像机目标
# description :摄像机目标
# author :Python超人
# date :2023-11-10
# link :https://gitcode.net/pythoncr/
# python_version :3.9
# ==============================================================================
from objs.obj import Obj
class CameraTarget(Obj):
"""
摄像机目标
"""
def __init__(self, name="摄像机目标", mass=5.97237e24,
init_position=[0, 0, 0],
init_velocity=[0, 0, 0],
texture="", size_scale=1.0, distance_scale=1.0,
ignore_mass=False, density=1e3, color=(7, 0, 162),
trail_color=None, trail_scale_factor=0.2, show_name=False,
parent=None, gravity_only_for=[]):
params = {
"name": name,
"mass": mass,
"init_position": init_position,
"init_velocity": init_velocity,
"density": density,
"color": color,
"texture": texture,
"size_scale": size_scale,
"distance_scale": distance_scale,
"ignore_mass": ignore_mass,
"trail_color": trail_color,
"trail_scale_factor": trail_scale_factor,
"show_name": show_name,
"parent": parent,
"gravity_only_for": gravity_only_for,
"model": "sphere"
}
super().__init__(**params)
self.set_ignore_gravity(True)
self.set_light_disable(True)
if __name__ == '__main__':
camera_target = CameraTarget()
print(camera_target)
camera_target.show_demo(size_scale=1000000)
...@@ -45,4 +45,4 @@ class Football(Obj): ...@@ -45,4 +45,4 @@ class Football(Obj):
if __name__ == '__main__': if __name__ == '__main__':
football = Football() football = Football()
print(football) print(football)
football.show_demo() football.show_demo(size_scale=1000000)
...@@ -500,11 +500,8 @@ class Obj(metaclass=ABCMeta): ...@@ -500,11 +500,8 @@ class Obj(metaclass=ABCMeta):
if callable(on_timer_changed_fun): if callable(on_timer_changed_fun):
on_timer_changed_fun(time_data) on_timer_changed_fun(time_data)
# 运行前会触发 on_ready
if on_ready_fun is not None:
UrsinaEvent.on_ready_subscription(on_ready) UrsinaEvent.on_ready_subscription(on_ready)
if on_timer_changed_fun is not None:
UrsinaEvent.on_timer_changed_subscription(on_timer_changed) UrsinaEvent.on_timer_changed_subscription(on_timer_changed)
ursina_run(bodies=[self], position=(0, 3000000, -9000000)) ursina_run(bodies=[self], position=(0, 3000000, -9000000))
......
...@@ -70,7 +70,7 @@ class HalleyCometSim(HalleyCometSimBase): ...@@ -70,7 +70,7 @@ class HalleyCometSim(HalleyCometSimBase):
# self.neptune, # 海王星 # self.neptune, # 海王星
# ] # ]
# self.bodies = self.bodies[:1] self.bodies = self.bodies[:1]
# 创建哈雷彗星创建哈雷彗星 # 创建哈雷彗星创建哈雷彗星
self.halley_comet = create_halley_comet(self.params.init_velocity, self.params.init_position) self.halley_comet = create_halley_comet(self.params.init_velocity, self.params.init_position)
...@@ -111,7 +111,7 @@ class HalleyCometSim(HalleyCometSimBase): ...@@ -111,7 +111,7 @@ class HalleyCometSim(HalleyCometSimBase):
print(dt.strftime('%Y-%m-%d %H:%M:%S')) print(dt.strftime('%Y-%m-%d %H:%M:%S'))
def calc_simulator(params): def calc_simulator(params, factor=1):
from sim_scenes.func import calc_run from sim_scenes.func import calc_run
from simulators.calc_simulator import CalcSimulator, CalcContext from simulators.calc_simulator import CalcSimulator, CalcContext
...@@ -234,25 +234,24 @@ def calc_simulator(params): ...@@ -234,25 +234,24 @@ def calc_simulator(params):
CalcSimulator.on_before_evolve_subscription(before_evolve) CalcSimulator.on_before_evolve_subscription(before_evolve)
CalcSimulator.on_finished_subscription(on_finished) CalcSimulator.on_finished_subscription(on_finished)
calc_run(sim.bodies, SECONDS_PER_YEAR, evolve_next=evolve_next) calc_run(sim.bodies, SECONDS_PER_YEAR * factor, evolve_next=evolve_next)
return sim.result return sim.result
def target_function(x, y, z): def target_function(x, y, z, factor):
params = HalleyCometParams( params = HalleyCometParams(
start_time='1982-09-24 00:00:00', start_time='1982-09-24 00:00:00',
# init_velocity=[-2.836 + (x / 1000), 4.705 + (y / 1000), 8.85 + (z / 1000)], # init_velocity=[-2.836 + (x / 1000), 4.705 + (y / 1000), 8.85 + (z / 1000)],
init_velocity=[x, y, z], init_velocity=[x, y, z],
init_position=[0, -5 * AU, -10 * AU] init_position=[0, -5 * AU, -10 * AU]
) )
return calc_simulator(params) return calc_simulator(params, factor)
if __name__ == '__main__': if __name__ == '__main__':
pass pass
# 近日点 0.586 AU # 近日点 0.586 AU
# 上次通过近日点: 1986年2月9日 # 上次通过近日点: 1986年2月9日
# 下次通过近日点: 2061年7月28日 # 下次通过近日点: 2061年7月28日
...@@ -286,8 +285,7 @@ if __name__ == '__main__': ...@@ -286,8 +285,7 @@ if __name__ == '__main__':
# init_velocity=[-2.841, 4.7, 8.86], # init_velocity=[-2.841, 4.7, 8.86],
# init_position=[0, -5 * AU, -10 * AU] # init_position=[0, -5 * AU, -10 * AU]
# 2023年12月9日 - 1986年2月9日 = 13817
# 35.1AU 0.586AU
# target_function(-2.836, 4.705, 8.85) # target_function(-2.836, 4.705, 8.85)
# target_function(-2.816, 4.725, 8.86) # 远日点:35.276 AU, 近日点:0.576 AU, 天数: 13821 # target_function(-2.816, 4.725, 8.86) # 远日点:35.276 AU, 近日点:0.576 AU, 天数: 13821
# target_function(-2.816, 4.725, 8.855) # 远日点:35.212 AU, 近日点:0.576 AU, 天数: 13785 # target_function(-2.816, 4.725, 8.855) # 远日点:35.212 AU, 近日点:0.576 AU, 天数: 13785
...@@ -307,7 +305,26 @@ if __name__ == '__main__': ...@@ -307,7 +305,26 @@ if __name__ == '__main__':
# target_function(-2.835, 4.72, 8.847) # 远日点:35.144 AU, 近日点:0.586 AU, 天数: 13748 # target_function(-2.835, 4.72, 8.847) # 远日点:35.144 AU, 近日点:0.586 AU, 天数: 13748
# target_function(-2.835, 4.71, 8.86) # 远日点:35.243 AU, 近日点:0.584 AU, 天数: 13809 # target_function(-2.835, 4.71, 8.86) # 远日点:35.243 AU, 近日点:0.584 AU, 天数: 13809
# target_function(-2.835, 4.73, 8.85) # OK 远日点:35.251 AU, 近日点:0.585 AU, 天数: 13815 # target_function(-2.835, 4.73, 8.85) # OK 远日点:35.251 AU, 近日点:0.585 AU, 天数: 13815
# a, b, c = target_function(-2.47, 5.13, 8.73)
# 2023年12月9日 - 1986年2月9日 = 13817
# 35.1AU 0.586AU
a, b, c = target_function(-2.774, 5.126, 8.65, 1 / 8)
# (-2.774, 5.126, 8.65, 1 / 8) 远日点:35.143 AU, 近日点:0.586 AU, 天数: 13753
# (-2.775, 5.126, 8.65, 1 / 8) 远日点:35.146 AU, 近日点:0.587 AU, 天数: 13755
# (-2.775, 5.126, 8.648, 1 / 8) 远日点:35.122 AU, 近日点:0.587 AU, 天数: 13743
# (-2.775, 5.125, 8.65, 1 / 8) OK 远日点:35.137 AU, 近日点:0.587 AU, 天数: 13751
# (-2.775, 5.12, 8.65, 1 / 8) OK 远日点:35.101 AU, 近日点:0.586 AU, 天数: 13728
# (-2.774, 5.12, 8.66, 1 / 8) 远日点:35.222(124) AU, 近日点:0.585 AU, 天数: 13803(77)
# (-2.774, 5.13, 8.65, 1 / 8) 远日点:35.169(71) AU, 近日点:0.587 AU, 天数: 13770(51)
# (-2.774, 5.12, 8.65, 1 / 8) OK 远日点:35.098 AU, 近日点:0.586 AU, 天数: 13726
# (-2.775, 5.13, 8.65, 1 / 8) 远日点:35.175 AU, 近日点:0.587 AU, 天数: 13773
# (-2.778, 5.13, 8.65, 1 / 8) OK 远日点:35.184 AU, 近日点:0.588 AU, 天数: 13779
# (-2.77, 5.12, 8.65, 1 / 8) OK 远日点:35.083 AU, 近日点:0.584 AU, 天数: 13714
# (-2.78, 5.11, 8.65, 1 / 8) OK 远日点:35.046 AU, 近日点:0.587 AU, 天数: 13696
# (-2.80, 5.10, 8.65, 1 / 8) OK 远日点:35.044 AU, 近日点:0.595 AU, 天数: 13698
# (-2.47, 5.13, 8.73, 1 / 12) 远日点:35.155 AU, 近日点:0.468 AU, 天数: 13690
# [-2.5, 5.02, 8.763] 远日点:35.032 AU, 近日点:0.477 AU, 天数: 13615 # [-2.5, 5.02, 8.763] 远日点:35.032 AU, 近日点:0.477 AU, 天数: 13615
# [-2.835, 4.81, 8.8] 远日点:35.161 AU, 近日点:0.591 AU, 天数: 13754 # [-2.835, 4.81, 8.8] 远日点:35.161 AU, 近日点:0.591 AU, 天数: 13754
...@@ -326,18 +343,18 @@ if __name__ == '__main__': ...@@ -326,18 +343,18 @@ if __name__ == '__main__':
# 远日点: 35.086 AU((40, 346, 14946.8522)) # 远日点: 35.086 AU((40, 346, 14946.8522))
# 近日点: 0.586 AU((3, 133, 1228.3418)) # 近日点: 0.586 AU((3, 133, 1228.3418))
# 远\近日天数: 13718 天 # 远\近日天数: 13718 天
R = 2 # R = 2
# X, Y, Z = -2.835, 4.73, 8.85 # # X, Y, Z = -2.835, 4.73, 8.85
X, Y, Z = -2.835, 4.72, 8.847 # X, Y, Z = -2.835, 4.72, 8.847
X, Y, Z = -2.826, 4.695, 8.86 # X, Y, Z = -2.826, 4.695, 8.86
idx = 0 # idx = 0
for x in range(-R, R + 1): # for x in range(-R, R + 1):
for y in range(-R, R + 1): # for y in range(-R, R + 1):
for z in range(-R, R + 1): # for z in range(-R, R + 1):
x, y, z = X + (x / 100), Y + (y / 100), Z + (z / 100) # x, y, z = X + (x / 100), Y + (y / 100), Z + (z / 100)
idx += 1 # idx += 1
print(f"Index:{idx} ---------------------------") # print(f"Index:{idx} ---------------------------")
a, b, c = target_function(x, y, z) # a, b, c = target_function(x, y, z)
# def t(): # def t():
# global idx # global idx
# params = HalleyCometParams( # params = HalleyCometParams(
......
...@@ -43,11 +43,13 @@ def create_halley_comet(init_velocity, init_position): ...@@ -43,11 +43,13 @@ def create_halley_comet(init_velocity, init_position):
def create_orbit_line(center_body, body, start_time): def create_orbit_line(center_body, body, start_time):
if not hasattr(body, "orbital_days"):
return None
orbital_days = int(math.ceil(body.orbital_days)) orbital_days = int(math.ceil(body.orbital_days))
points = get_reality_orbit_points(type(body).__name__.lower(), start_time=start_time, days=orbital_days, points = get_reality_orbit_points(type(body).__name__.lower(), start_time=start_time, days=orbital_days,
segments=100) segments=100)
# print(points) # print(points)
orbit_line = create_orbit_by_points(center_body.position, points, line_color=body.trail_color) orbit_line = create_orbit_by_points(center_body.position, points, line_color=body.trail_color, alpha=0.3)
return orbit_line return orbit_line
......
...@@ -7,13 +7,13 @@ ...@@ -7,13 +7,13 @@
# python_version :3.9 # python_version :3.9
# ============================================================================== # ==============================================================================
from ursina import camera, application from ursina import camera, application, lerp, Vec3
from common.celestial_data_service import init_bodies_reality_pos_vels, conv_to_astropy_time, \ from common.celestial_data_service import init_bodies_reality_pos_vels, conv_to_astropy_time, \
set_solar_system_celestial_position set_solar_system_celestial_position
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, CameraTarget
from sim_scenes.func import create_text_panel, camera_look_at from sim_scenes.func import create_text_panel, camera_look_at
from sim_scenes.func import ursina_run, create_sphere_sky from sim_scenes.func import ursina_run, create_sphere_sky
from sim_scenes.solar_system.halley_comet_lib import HalleyCometSimBase, HalleyCometParams, \ from sim_scenes.solar_system.halley_comet_lib import HalleyCometSimBase, HalleyCometParams, \
...@@ -25,6 +25,8 @@ from simulators.ursina.ursina_config import UrsinaConfig ...@@ -25,6 +25,8 @@ 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_label from simulators.ursina.ursina_mesh import create_label
RUN_SPEED = 1 / 8
class HalleyCometSim(HalleyCometSimBase): class HalleyCometSim(HalleyCometSimBase):
""" """
...@@ -54,6 +56,9 @@ class HalleyCometSim(HalleyCometSimBase): ...@@ -54,6 +56,9 @@ class HalleyCometSim(HalleyCometSimBase):
# 创建哈雷彗星创建哈雷彗星 # 创建哈雷彗星创建哈雷彗星
self.halley_comet = create_halley_comet(self.params.init_velocity, self.params.init_position) self.halley_comet = create_halley_comet(self.params.init_velocity, self.params.init_position)
self.bodies.append(self.halley_comet) self.bodies.append(self.halley_comet)
# # 创建一个摄像机跟踪目标
# self.camera_target = CameraTarget(size_scale=1e9)
# self.bodies.append(self.camera_target)
def init_settings(self): def init_settings(self):
""" """
...@@ -65,8 +70,9 @@ class HalleyCometSim(HalleyCometSimBase): ...@@ -65,8 +70,9 @@ class HalleyCometSim(HalleyCometSimBase):
# UrsinaConfig.trail_type = "curve_line" # UrsinaConfig.trail_type = "curve_line"
# UrsinaConfig.trail_length = 300 # UrsinaConfig.trail_length = 300
UrsinaConfig.trail_type = "line" UrsinaConfig.trail_type = "line"
UrsinaConfig.trail_length = 152 # UrsinaConfig.trail_length = 152 # 尾巴数量刚刚好
UrsinaConfig.trail_thickness_factor = 5 UrsinaConfig.trail_length = 135
UrsinaConfig.trail_thickness_factor = 3
# UrsinaConfig.trail_length = 180 # UrsinaConfig.trail_length = 180
UrsinaConfig.trail_factor = 3 UrsinaConfig.trail_factor = 3
...@@ -75,6 +81,15 @@ class HalleyCometSim(HalleyCometSimBase): ...@@ -75,6 +81,15 @@ class HalleyCometSim(HalleyCometSimBase):
application.time_scale = 5 application.time_scale = 5
camera.forward_factor = 0
def camera_update():
camera_look_at(self.halley_comet, rotation_z=0)
if camera.forward_factor != 0:
camera.position += camera.forward * camera.forward_factor
camera.update = camera_update
def on_ready(self): def on_ready(self):
""" """
事件绑定后,模拟器运行前会触发 事件绑定后,模拟器运行前会触发
...@@ -98,9 +113,8 @@ class HalleyCometSim(HalleyCometSimBase): ...@@ -98,9 +113,8 @@ class HalleyCometSim(HalleyCometSimBase):
""" """
self.orbit_lines = [] self.orbit_lines = []
for body in self.bodies[1:]: for body in self.bodies[1:]:
if isinstance(body, HalleComet):
continue
orbit_line = create_orbit_line(self.sun, body, self.start_time) orbit_line = create_orbit_line(self.sun, body, self.start_time)
if orbit_line is not None:
self.orbit_lines.append(orbit_line) self.orbit_lines.append(orbit_line)
def set_bodies_position(self, time_data: TimeData): def set_bodies_position(self, time_data: TimeData):
...@@ -166,14 +180,60 @@ class HalleyCometSim(HalleyCometSimBase): ...@@ -166,14 +180,60 @@ class HalleyCometSim(HalleyCometSimBase):
@param dt: @param dt:
@return: @return:
""" """
milestones = ["1986-02-09", "2023-12-09", "2061-07-28"] milestones = [("1986-02-09", (0, 2, 0)), ("2023-12-09", (0, -2, 0)), ("2061-07-28", (0, 2, 0))]
for milestone in milestones: for milestone, pos in milestones:
prop_name = f"milestone_{milestone}" prop_name = f"milestone_{milestone}"
if not hasattr(self, prop_name) and dt.strftime("%Y-%m-%d") >= milestone: if not hasattr(self, prop_name) and dt.strftime("%Y-%m-%d") >= milestone:
setattr(self, prop_name, milestone) setattr(self, prop_name, milestone)
self.create_year_label(last_trail, milestone, pos=(0, 2, 0), scale=100, background=True) if pos is None:
application.paused = True pos = (0, 2, 0)
UrsinaEvent.on_pause() self.create_year_label(last_trail, milestone, pos=pos, scale=60, background=True)
# application.paused = True
# UrsinaEvent.on_pause()
def look_at_halley_comet(self, dt):
forward_infos = [
(1983, 0.1 * RUN_SPEED * 12),
(1986, -8 * RUN_SPEED * 12),
(1987, -3 * RUN_SPEED * 12),
(1988, 0),
(2049, 1 * RUN_SPEED * 12),
(2061, 0),
(2062, -5 * RUN_SPEED * 12),
(2065, 0),
(2100, 0),
(2124, 0)
]
for idx, (year, factor) in enumerate(forward_infos[:-1]):
next_year = forward_infos[idx + 1][0]
if next_year > dt.year >= year:
if factor < 0 and camera.position[0] < -3000:
# 最远
continue
camera.forward_factor = factor
# if dt.year > 1986:
# self.camera_target.planet.look_at(self.halley_comet.planet)
# self.camera_target.planet.position = \
# lerp(self.camera_target.planet.position, self.halley_comet.planet.position, 1)
# print(self.camera_target.planet.position, self.halley_comet.planet.position)
# camera_look_at(self.halley_comet, rotation_z=0)
# if 2000 > dt.year >= 1986:
# camera.forward_factor = -0.3 * RUN_SPEED * 12
# elif 2008 > dt.year >= 2000:
# camera.forward_factor = 0
# elif 2064 > dt.year >= 2008:
# camera.forward_factor = 0.3 * RUN_SPEED * 12
# def camera_update():
# camera_look_at(self.halley_comet, rotation_z=0)
# camera.position += camera.forward * -0.3
#
# camera.forward = Vec3(0, 0, 0)
# camera.update = camera_update
# if dt.year > 1986:
# # camera.position += Vec3(0, 0, -1)
# camera.position += camera.forward * -5
def on_timer_changed(self, time_data): def on_timer_changed(self, time_data):
""" """
...@@ -184,7 +244,9 @@ class HalleyCometSim(HalleyCometSimBase): ...@@ -184,7 +244,9 @@ class HalleyCometSim(HalleyCometSimBase):
dt = time_data.get_datetime(str(self.start_time)) dt = time_data.get_datetime(str(self.start_time))
year = dt.strftime("%Y") year = dt.strftime("%Y")
camera_look_at(self.halley_comet) # camera_look_at(self.halley_comet)
self.look_at_halley_comet(dt)
if hasattr(self, "halley_comet"): if hasattr(self, "halley_comet"):
if self.halley_comet.planet.enabled: if self.halley_comet.planet.enabled:
...@@ -281,7 +343,9 @@ if __name__ == '__main__': ...@@ -281,7 +343,9 @@ if __name__ == '__main__':
start_time='1982-09-24 00:00:00', start_time='1982-09-24 00:00:00',
# init_velocity=[-2.835, 4.72, 8.847], # init_velocity=[-2.835, 4.72, 8.847],
# init_velocity=[-2.826, 4.695, 8.86], # init_velocity=[-2.826, 4.695, 8.86],
init_velocity=[-2.836, 4.705, 8.85], # init_velocity=[-2.836, 4.705, 8.85],
# init_velocity=[-2.80, 5.10, 8.65], # 1/8
init_velocity=[-2.774, 5.126, 8.65], # 1/8
init_position=[0, -5 * AU, -10 * AU] init_position=[0, -5 * AU, -10 * AU]
) )
...@@ -299,14 +363,14 @@ if __name__ == '__main__': ...@@ -299,14 +363,14 @@ if __name__ == '__main__':
# 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹
# position = 左-右+、上+下-、前+后- # position = 左-右+、上+下-、前+后-
ursina_run(sim.bodies, ursina_run(sim.bodies,
SECONDS_PER_YEAR, SECONDS_PER_YEAR * RUN_SPEED,
# position=(0, 2 * AU, -11 * AU), # position=(0, 2 * AU, -11 * AU),
# position=(0, 0.5 * AU, -5 * AU), # position=(0, 0.5 * AU, -5 * AU),
position=(0, AU, -20 * AU), position=(2 * AU, -5 * AU, -20 * AU),
cosmic_bg='', cosmic_bg='',
show_trail=True, show_trail=True,
# 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, timer_enabled=True,
show_grid=False show_grid=False
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册