# -*- coding:utf-8 -*- # title :哈雷彗星场景半真实模拟共用库 # description : # author :Python超人 # date :2023-11-06 # link :https://gitcode.net/pythoncr/ # python_version :3.9 # ============================================================================== import math from dataclasses import dataclass from dataclasses import field from bodies import Sun, Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto from common.celestial_data_service import get_reality_orbit_points, init_bodies_reality_pos_vels, init_bodies_pos_vels from common.color_utils import trail_color_brightest from common.consts import AU from objs import HalleComet from sim_scenes.universe_sim_scenes import UniverseSimScenes from simulators.ursina.ui.control_ui import ControlUI from simulators.ursina.ursina_mesh import create_orbit_by_points @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]) def create_halley_comet(init_velocity, init_position): """ 创建哈雷彗星 @return: """ # 哈雷彗星的平均运行速度约为每小时 70,000 英里或每小时 126,000 公里 。(35公里/秒) # 每76.1年环绕太阳一周的周期彗星 halley_comet = HalleComet( # size_scale=4e7, size_scale=0.15e8, init_velocity=init_velocity, init_position=init_position) \ .set_light_disable(True) return halley_comet def create_orbit_line(center_body, body, start_time, alpha=0.2): 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, alpha=alpha) return orbit_line class HalleyCometSimBase(UniverseSimScenes): def __init__(self): self.mercury = None self.sun = None self.venus = None self.earth = None self.mars = None self.jupiter = None self.saturn = None self.uranus = None self.neptune = None self.pluto = None self.bodies = [] # def set_window_size(self, size=(1536, 684), fullscreen=False): # from ursina import window # if fullscreen: # # 设置窗口为全屏模式 # window.fullscreen = True # # # 设置窗口的宽度和高度 # window.size = size # # self.set_window_size((3500, 1024)) # # r = 1 # # self.set_window_size((1920*2, 1080*2)) # # self.set_window_size((int(1920 * r), int(1080 * r))) # # self.set_window_size((2376, 1080)) # # self.set_window_size((520, 540), fullscreen=False) def build_solar_system(self, ignore_gravity=False, start_time=None): # region 构建太阳系 show_trail = False self.sun = Sun(size_scale=0.6e2, show_trail=show_trail) self.mercury = Mercury(size_scale=5e3, show_trail=show_trail) self.venus = Venus(size_scale=3e3, show_trail=show_trail) self.earth = Earth(size_scale=3e3, rotate_angle=0, show_trail=show_trail) self.mars = Mars(size_scale=4e3, show_trail=show_trail) self.jupiter = Jupiter(size_scale=0.8e3, show_trail=show_trail) self.saturn = Saturn(size_scale=0.8e3, show_trail=show_trail) self.uranus = Uranus(size_scale=3e3, show_trail=show_trail) self.neptune = Neptune(size_scale=3e3, show_trail=show_trail) self.pluto = Pluto(size_scale=1e5, show_trail=show_trail) self.bodies = [ self.sun, # 太阳 self.mercury, # 水星 self.venus, # 金星 self.earth, # 地球 self.mars, # 火星 self.jupiter, # 木星 self.saturn, # 土星 self.uranus, # 天王星 self.neptune, # 海王星 # self.pluto, # 冥王星 ] trail_color_brightest(self.bodies) if start_time is not None: init_bodies_reality_pos_vels(self.bodies, start_time) else: init_bodies_pos_vels(self.bodies) if ignore_gravity: for body in self.bodies[1:]: body.init_velocity = [0, 0, 0] body.set_ignore_gravity(True) def show_grid_axises(self): """ 显示网格以及坐标线 @return: """ from simulators.ursina.entities.world_grid import WorldGrid WorldGrid().draw_axises(10) def show_clock(self, dt): """ 显示时钟 @param dt: 时间 datetime @return: """ # if self.clock_position_center: # position, origin = (0, .25), (0, 0), # else: from ursina import window aspect_ratio = window.aspect_ratio position, origin = (0.5 * aspect_ratio - 0.25, -0.45), (-0.5, 0.5), ControlUI.current_ui.show_message(dt.strftime(' %Y-%m-%d'), position=position, origin=origin, # font="verdana.ttf", font="fonts/Digital-7Mono.TTF", font_scale=1.35, font_color=(0, 255, 0), close_time=-1) # ControlUI.current_ui.show_message(dt.strftime(' %Y-%m-%d %H:%M:%S'), # position=position, # origin=origin, # # font="verdana.ttf", # font="fonts/Digital-7Mono.TTF", # font_scale=1.35, # font_color=(0, 255, 0), # close_time=-1) def interval_run(self, total_times, interval, fun, fun_args=None): """ 需要注意的是 total_times 前后之间的间隔大于 interval,基本上是每次都运行。 @param total_times: @param interval: @param fun: @param fun_args: @return: """ if not hasattr(self, "interval_method_register"): self.interval_method_register = {} if fun not in self.interval_method_register.keys(): self.interval_method_register[fun] = total_times if fun_args is None: fun() elif len(fun_args) == 1: fun(fun_args[0]) elif len(fun_args) > 1: fun(*fun_args) else: if total_times - self.interval_method_register[fun] > interval: if fun_args is None: fun() elif len(fun_args) == 1: fun(fun_args[0]) elif len(fun_args) > 1: fun(*fun_args) self.interval_method_register[fun] = total_times