From dd177140437e37bd5c538e784885b2b8e2fe7ad2 Mon Sep 17 00:00:00 2001 From: march3 Date: Fri, 10 Nov 2023 14:50:21 +0800 Subject: [PATCH] =?UTF-8?q?Python=E8=B6=85=E4=BA=BA-=E5=AE=87=E5=AE=99?= =?UTF-8?q?=E6=A8=A1=E6=8B=9F=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- objs/__init__.py | 1 + objs/camera_target.py | 50 +++++++++++ objs/football.py | 2 +- objs/obj.py | 7 +- sim_lab/halley_comet_research_calc.py | 59 ++++++++----- sim_scenes/solar_system/halley_comet_lib.py | 4 +- sim_scenes/solar_system/halley_comet_sim.py | 98 +++++++++++++++++---- 7 files changed, 176 insertions(+), 45 deletions(-) create mode 100644 objs/camera_target.py diff --git a/objs/__init__.py b/objs/__init__.py index f10e3f1..47cabce 100644 --- a/objs/__init__.py +++ b/objs/__init__.py @@ -13,4 +13,5 @@ from objs.sci_fi_bomber import SciFiBomber from objs.water_drop import WaterDrop from objs.sci_fi_gunship import ScifiGunship from objs.halley_comet import HalleComet +from objs.camera_target import CameraTarget diff --git a/objs/camera_target.py b/objs/camera_target.py new file mode 100644 index 0000000..f946ad3 --- /dev/null +++ b/objs/camera_target.py @@ -0,0 +1,50 @@ +# -*- 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) diff --git a/objs/football.py b/objs/football.py index a3fff35..9c838e6 100644 --- a/objs/football.py +++ b/objs/football.py @@ -45,4 +45,4 @@ class Football(Obj): if __name__ == '__main__': football = Football() print(football) - football.show_demo() + football.show_demo(size_scale=1000000) diff --git a/objs/obj.py b/objs/obj.py index 6ff9a53..60c86a9 100644 --- a/objs/obj.py +++ b/objs/obj.py @@ -500,12 +500,9 @@ class Obj(metaclass=ABCMeta): if callable(on_timer_changed_fun): 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)) diff --git a/sim_lab/halley_comet_research_calc.py b/sim_lab/halley_comet_research_calc.py index 7b59514..c699c8d 100644 --- a/sim_lab/halley_comet_research_calc.py +++ b/sim_lab/halley_comet_research_calc.py @@ -70,7 +70,7 @@ class HalleyCometSim(HalleyCometSimBase): # 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) @@ -111,7 +111,7 @@ class HalleyCometSim(HalleyCometSimBase): 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 simulators.calc_simulator import CalcSimulator, CalcContext @@ -234,25 +234,24 @@ def calc_simulator(params): CalcSimulator.on_before_evolve_subscription(before_evolve) 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 -def target_function(x, y, z): +def target_function(x, y, z, factor): params = HalleyCometParams( start_time='1982-09-24 00:00:00', # init_velocity=[-2.836 + (x / 1000), 4.705 + (y / 1000), 8.85 + (z / 1000)], init_velocity=[x, y, z], init_position=[0, -5 * AU, -10 * AU] ) - return calc_simulator(params) + return calc_simulator(params, factor) if __name__ == '__main__': pass - # 近日点 0.586 AU # 上次通过近日点: 1986年2月9日 # 下次通过近日点: 2061年7月28日 @@ -286,8 +285,7 @@ if __name__ == '__main__': # init_velocity=[-2.841, 4.7, 8.86], # 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.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 @@ -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.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 - # 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.835, 4.81, 8.8] 远日点:35.161 AU, 近日点:0.591 AU, 天数: 13754 @@ -326,18 +343,18 @@ if __name__ == '__main__': # 远日点: 35.086 AU((40, 346, 14946.8522)) # 近日点: 0.586 AU((3, 133, 1228.3418)) # 远\近日天数: 13718 天 - R = 2 - # X, Y, Z = -2.835, 4.73, 8.85 - X, Y, Z = -2.835, 4.72, 8.847 - X, Y, Z = -2.826, 4.695, 8.86 - idx = 0 - for x in range(-R, R + 1): - for y in range(-R, R + 1): - for z in range(-R, R + 1): - x, y, z = X + (x / 100), Y + (y / 100), Z + (z / 100) - idx += 1 - print(f"Index:{idx} ---------------------------") - a, b, c = target_function(x, y, z) + # R = 2 + # # X, Y, Z = -2.835, 4.73, 8.85 + # X, Y, Z = -2.835, 4.72, 8.847 + # X, Y, Z = -2.826, 4.695, 8.86 + # idx = 0 + # for x in range(-R, R + 1): + # for y in range(-R, R + 1): + # for z in range(-R, R + 1): + # x, y, z = X + (x / 100), Y + (y / 100), Z + (z / 100) + # idx += 1 + # print(f"Index:{idx} ---------------------------") + # a, b, c = target_function(x, y, z) # def t(): # global idx # params = HalleyCometParams( diff --git a/sim_scenes/solar_system/halley_comet_lib.py b/sim_scenes/solar_system/halley_comet_lib.py index 5fe6c5b..eab7f05 100644 --- a/sim_scenes/solar_system/halley_comet_lib.py +++ b/sim_scenes/solar_system/halley_comet_lib.py @@ -43,11 +43,13 @@ def create_halley_comet(init_velocity, init_position): 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)) points = get_reality_orbit_points(type(body).__name__.lower(), start_time=start_time, days=orbital_days, segments=100) # 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 diff --git a/sim_scenes/solar_system/halley_comet_sim.py b/sim_scenes/solar_system/halley_comet_sim.py index 0736a57..818ae70 100644 --- a/sim_scenes/solar_system/halley_comet_sim.py +++ b/sim_scenes/solar_system/halley_comet_sim.py @@ -7,13 +7,13 @@ # 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, \ set_solar_system_celestial_position from common.consts import SECONDS_PER_YEAR, AU 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 ursina_run, create_sphere_sky from sim_scenes.solar_system.halley_comet_lib import HalleyCometSimBase, HalleyCometParams, \ @@ -25,6 +25,8 @@ from simulators.ursina.ursina_config import UrsinaConfig from simulators.ursina.ursina_event import UrsinaEvent from simulators.ursina.ursina_mesh import create_label +RUN_SPEED = 1 / 8 + 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.bodies.append(self.halley_comet) + # # 创建一个摄像机跟踪目标 + # self.camera_target = CameraTarget(size_scale=1e9) + # self.bodies.append(self.camera_target) def init_settings(self): """ @@ -65,8 +70,9 @@ class HalleyCometSim(HalleyCometSimBase): # UrsinaConfig.trail_type = "curve_line" # UrsinaConfig.trail_length = 300 UrsinaConfig.trail_type = "line" - UrsinaConfig.trail_length = 152 - UrsinaConfig.trail_thickness_factor = 5 + # UrsinaConfig.trail_length = 152 # 尾巴数量刚刚好 + UrsinaConfig.trail_length = 135 + UrsinaConfig.trail_thickness_factor = 3 # UrsinaConfig.trail_length = 180 UrsinaConfig.trail_factor = 3 @@ -75,6 +81,15 @@ class HalleyCometSim(HalleyCometSimBase): 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): """ 事件绑定后,模拟器运行前会触发 @@ -98,10 +113,9 @@ class HalleyCometSim(HalleyCometSimBase): """ self.orbit_lines = [] for body in self.bodies[1:]: - if isinstance(body, HalleComet): - continue orbit_line = create_orbit_line(self.sun, body, self.start_time) - self.orbit_lines.append(orbit_line) + if orbit_line is not None: + self.orbit_lines.append(orbit_line) def set_bodies_position(self, time_data: TimeData): """ @@ -166,14 +180,60 @@ class HalleyCometSim(HalleyCometSimBase): @param dt: @return: """ - milestones = ["1986-02-09", "2023-12-09", "2061-07-28"] - for milestone in milestones: + milestones = [("1986-02-09", (0, 2, 0)), ("2023-12-09", (0, -2, 0)), ("2061-07-28", (0, 2, 0))] + for milestone, pos in milestones: prop_name = f"milestone_{milestone}" if not hasattr(self, prop_name) and dt.strftime("%Y-%m-%d") >= milestone: setattr(self, prop_name, milestone) - self.create_year_label(last_trail, milestone, pos=(0, 2, 0), scale=100, background=True) - application.paused = True - UrsinaEvent.on_pause() + if pos is None: + pos = (0, 2, 0) + 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): """ @@ -184,7 +244,9 @@ class HalleyCometSim(HalleyCometSimBase): dt = time_data.get_datetime(str(self.start_time)) 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 self.halley_comet.planet.enabled: @@ -281,7 +343,9 @@ if __name__ == '__main__': start_time='1982-09-24 00:00:00', # init_velocity=[-2.835, 4.72, 8.847], # 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] ) @@ -299,14 +363,14 @@ if __name__ == '__main__': # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 # position = 左-右+、上+下-、前+后- ursina_run(sim.bodies, - SECONDS_PER_YEAR, + SECONDS_PER_YEAR * RUN_SPEED, # position=(0, 2 * AU, -11 * AU), # position=(0, 0.5 * AU, -5 * AU), - position=(0, AU, -20 * AU), + position=(2 * AU, -5 * AU, -20 * AU), cosmic_bg='', show_trail=True, # bg_music='sounds/no_glory.mp3', - show_camera_info=False, + # show_camera_info=False, show_control_info=False, timer_enabled=True, show_grid=False -- GitLab