From 8e7a719979cd70706fba50e2ff223fb55ceaf5b5 Mon Sep 17 00:00:00 2001 From: march3 Date: Sat, 11 Nov 2023 19:31:39 +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 --- sim_scenes/solar_system/halley_comet_sim.py | 215 +++++++++++++------- sim_scenes/universe_sim_scenes.py | 2 + simulators/ursina/entities/body_timer.py | 11 +- 3 files changed, 151 insertions(+), 77 deletions(-) diff --git a/sim_scenes/solar_system/halley_comet_sim.py b/sim_scenes/solar_system/halley_comet_sim.py index a1c184b..997879a 100644 --- a/sim_scenes/solar_system/halley_comet_sim.py +++ b/sim_scenes/solar_system/halley_comet_sim.py @@ -151,8 +151,9 @@ class HalleyCometSim(HalleyCometSimBase): scale=scale, alpha=1.0, background=background ) label.set_light_off() + self.last_year = year - def set_comet_trail_alpha(self, distance_sun): + def update_comet_trail_alpha(self, distance_sun): """ 根据彗哈雷星和太阳的距离,设置彗星尾巴的透明度来模仿接近太阳有慧尾,离开太阳到一定距离就渐渐消失 @param distance_sun: 彗哈雷星和太阳的距离 @@ -204,6 +205,12 @@ class HalleyCometSim(HalleyCometSimBase): return get_run_speed_factor() * value def camera_move(self, dt): + """ + 摄像机移动控制 + @param dt: + @return: + """ + # 摄像机移动控制数据 camera_move_infos = [ # 条件:年份 # 移动的信息: @@ -229,90 +236,148 @@ class HalleyCometSim(HalleyCometSimBase): @param time_data: @return: """ - dt = time_data.get_datetime(str(self.start_time)) - year = dt.strftime("%Y") - + dt = time_data.get_datetime(self.start_time) + # 摄像机看向哈雷彗星 camera_look_at(self.halley_comet, rotation_z=0) - self.camera_move(dt) - - if hasattr(self, "halley_comet"): - if self.halley_comet.planet.enabled: - self.halley_comet.planet.look_at(self.sun.planet) - d_sun = calculate_distance(self.halley_comet.position, self.sun.position) - d_earth = calculate_distance(self.halley_comet.position, self.earth.position) - trail_keys = self.halley_comet.planet.trails.keys() - if len(trail_keys) > 0: - last_trail = list(trail_keys)[-1] - if hasattr(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") - - pos = self.halley_comet.planet.position - - import copy - - if self.show_milestone_lable(last_trail, dt): - pass - elif not hasattr(self, "last_year"): - self.create_year_label(last_trail, year, pos) - elif self.last_year != year: - if not hasattr(self, "last_label_pos"): - self.create_year_label(last_trail, year, pos) - self.last_label_pos = copy.deepcopy(self.halley_comet.position) - else: - # 防止标签非常紧密 - d = calculate_distance(self.halley_comet.position, self.last_label_pos) - if d > 2 * AU: - self.create_year_label(last_trail, year, pos) - self.last_label_pos = copy.deepcopy(self.halley_comet.position) - - self.last_year = year - - # 哈雷彗星离太阳最近的点称为 "perihelion of Halley's Comet"(近日点:comet_peri), - if not hasattr(self, "comet_peri"): - self.comet_peri = d_sun - self.comet_peri_dt = dt.strftime("%Y-%m-%d") - elif d_sun < self.comet_peri: - self.comet_peri = d_sun - self.comet_peri_dt = dt.strftime("%Y-%m-%d") - - # 哈雷彗星离太阳最远的点称为 "aphelion of Halley's Comet"(远日点) - if not hasattr(self, "comet_aphel"): - self.comet_aphel = d_sun - self.comet_aphel_dt = dt.strftime("%Y-%m-%d") - elif d_sun > self.comet_aphel: - self.comet_aphel = d_sun - self.comet_aphel_dt = dt.strftime("%Y-%m-%d") - - self.set_comet_trail_alpha(d_sun) - - panel_text = "哈雷彗星:\n\n距离太阳:%.3f\tAU" % (d_sun / AU) - panel_text += "\n\n离日最远:%.3f\tAU" % (self.comet_aphel / AU) - panel_text += "\n\n离日最近:%.3f\tAU" % (self.comet_peri / AU) - velocity, _ = get_value_direction_vectors(self.halley_comet.velocity) - panel_text += "\n\n当前速度:%.3f\tkm/s" % velocity - - self.text_panel.text = panel_text - time_total_hours = time_data.total_hours if not hasattr(self, "last_total_hours"): self.last_total_hours = time_total_hours + self.update_halley_comet_info(dt) - # 每个一段时间运行一次更新(不要太频繁更新,会导致摄像机抖动) + # 每隔一段时间运行一次更新(不要太频繁更新,会导致摄像机抖动) if time_total_hours - self.last_total_hours > 100: - # 更新天体的位置 - self.set_bodies_position(time_data) - # 更新时钟 - self.show_clock(dt) - # 更新轨道的位置 - for i, orbit_line in enumerate(self.orbit_lines): - orbit_line.position = self.sun.planet.position - + self.camera_move(dt) + self.update_halley_comet_info(dt) + self.update_ui(time_data, dt) + # 记录最后更新的总耗时(小时) self.last_total_hours = time_total_hours + def check_create_year_label(self, last_trail, dt): + """ + 检测并创建年标签 + @param last_trail: + @param dt: + @return: + """ + if last_trail is None: + return + + import copy + year = dt.strftime("%Y") + pos = self.halley_comet.planet.position + # 里程碑标签 + if self.show_milestone_lable(last_trail, dt): + pass + elif not hasattr(self, "last_year"): + # 第一次运行,则创建“年标签” + self.create_year_label(last_trail, year, pos) + self.last_label_pos = copy.deepcopy(self.halley_comet.position) + elif self.last_year != year: + if hasattr(self, "last_label_pos"): + # 防止“年标签”显示非常紧密 + d = calculate_distance(self.halley_comet.position, self.last_label_pos) + if d > 2 * AU: + self.create_year_label(last_trail, year, pos) + self.last_label_pos = copy.deepcopy(self.halley_comet.position) + + def update_halley_comet_info(self, dt): + """ + 更新哈雷彗星的信息 + @param dt: + @return: + """ + # 哈雷彗星面向太阳,这样彗尾就远离太阳的方向 + self.halley_comet.planet.look_at(self.sun.planet) + + # 计算哈雷彗星与太阳、地球的距离 + d_sun = calculate_distance(self.halley_comet.position, self.sun.position) + d_earth = calculate_distance(self.halley_comet.position, self.earth.position) + # 哈雷彗星所有轨迹线(注意不是彗尾) + trail_keys = self.halley_comet.planet.trails.keys() + # 哈雷彗星有轨迹线 + if len(trail_keys) > 0: + # 找的最后的轨迹线 + last_trail = list(trail_keys)[-1] + if hasattr(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") + + # 检测并再轨迹线上创建年标签 + self.check_create_year_label(last_trail, dt) + + # 更新彗星尾巴的透明度 + self.update_comet_trail_alpha(d_sun) + + # 计算和更新近日点数据 + self.update_comet_peri(d_sun, dt) + # 计算和更新远日点数据 + self.update_comet_aphel(d_sun, dt) + # 更新文字信息面板 + self.update_text_panel(d_sun) + + def update_text_panel(self, d_sun): + """ + 更新文字信息面板 + @param d_sun: + @return: + """ + panel_text = "哈雷彗星:\n\n距离太阳:%.3f\tAU" % (d_sun / AU) + panel_text += "\n\n离日最远:%.3f\tAU" % (self.comet_aphel / AU) + panel_text += "\n\n离日最近:%.3f\tAU" % (self.comet_peri / AU) + velocity, _ = get_value_direction_vectors(self.halley_comet.velocity) + panel_text += "\n\n当前速度:%.3f\tkm/s" % velocity + + self.text_panel.text = panel_text + + def update_comet_aphel(self, d_sun, dt): + """ + 计算和更新远日点数据 + @param d_sun: + @param dt: + @return: + """ + # 哈雷彗星离太阳最远的点称为 "aphelion of Halley's Comet"(远日点) + if not hasattr(self, "comet_aphel"): + self.comet_aphel = d_sun + self.comet_aphel_dt = dt.strftime("%Y-%m-%d") + elif d_sun > self.comet_aphel: + self.comet_aphel = d_sun + self.comet_aphel_dt = dt.strftime("%Y-%m-%d") + + def update_comet_peri(self, d_sun, dt): + """ + 计算和更新近日点数据 + @param d_sun: + @param dt: + @return: + """ + # 哈雷彗星离太阳最近的点称为 "perihelion of Halley's Comet"(近日点:comet_peri), + if not hasattr(self, "comet_peri"): + self.comet_peri = d_sun + self.comet_peri_dt = dt.strftime("%Y-%m-%d") + elif d_sun < self.comet_peri: + self.comet_peri = d_sun + self.comet_peri_dt = dt.strftime("%Y-%m-%d") + + def update_ui(self, time_data, dt): + """ + 更新UI,包含天体的位置、时钟、轨道的位置 + @param time_data: + @param dt: + @return: + """ + # 更新天体的位置 + self.set_bodies_position(time_data) + # 更新时钟 + self.show_clock(dt) + # 更新轨道的位置(TODO:短时间可以忽略) + # for i, orbit_line in enumerate(self.orbit_lines): + # orbit_line.position = self.sun.planet.position + if __name__ == '__main__': """ diff --git a/sim_scenes/universe_sim_scenes.py b/sim_scenes/universe_sim_scenes.py index 5f8119e..894ce7b 100644 --- a/sim_scenes/universe_sim_scenes.py +++ b/sim_scenes/universe_sim_scenes.py @@ -29,3 +29,5 @@ class UniverseSimScenes: # self.set_window_size((int(1920 * r), int(1080 * r))) # self.set_window_size((2376, 1080)) # self.set_window_size((520, 540), fullscreen=False) + + diff --git a/simulators/ursina/entities/body_timer.py b/simulators/ursina/entities/body_timer.py index 9340237..ddea9f4 100644 --- a/simulators/ursina/entities/body_timer.py +++ b/simulators/ursina/entities/body_timer.py @@ -59,15 +59,21 @@ class TimeData: else: self.time_text = f'{self.hours:02d}:{self.minutes:02d}:{self.seconds:02d}' - def get_datetime(self, init_datetime): + """ + 根据初始化的时间,获取当前北京时间 + @param init_datetime: + @return: + """ import datetime + if not isinstance(init_datetime, str): + init_datetime = str(init_datetime) # UTC_format = "%Y-%m-%dT%H:%M:%S.%fZ" if len(init_datetime) == 19: init_datetime = init_datetime + ".000" UTC = datetime.datetime.strptime(init_datetime + "Z", "%Y-%m-%d %H:%M:%S.%fZ") # BJS_format = "%Y-%m-%d %H:%M:%S" - BJS = UTC + datetime.timedelta(hours=8+self.total_hours) + BJS = UTC + datetime.timedelta(hours=8 + self.total_hours) # BJS = BJS.strftime(BJS_format) # dt = datetime(init_datetime) return BJS @@ -89,6 +95,7 @@ class AppTimeUtil: """ 应用计数器工具类 """ + def __init__(self): self.arrival_time = -1 self.current_time = 0 -- GitLab