# -*- coding:utf-8 -*- # title :天体大小比较 # description :天体大小比较 # author :Python超人 # date :2024-01-24 # link :https://gitcode.net/pythoncr/ # python_version :3.9 # ============================================================================== import threading from bodies import Sun, Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto, Moon, Callisto, Europa, \ Ganymede, Sirius from bodies import Rigel, Bellatrix, Alcyone, Antares, Arcturus, Aldebaran, Betelgeuse from bodies import EtaCarinae, YCanumVenaticorum, VYCanisMajoris, UYScuti, CarinaeV382, Stephenson_2_18 from bodies.jupiter_system import Io from common.consts import SECONDS_PER_HOUR, SECONDS_PER_DAY, AU from sim_scenes.func import ursina_run, create_sphere_sky, camera_move_control, get_run_speed_factor from sim_scenes.universe_sim_scenes import UniverseSimScenes from simulators.ursina.entities.body_timer import TimeData, AppTimeUtil from simulators.ursina.entities.entity_utils import create_directional_light from simulators.ursina.ursina_event import UrsinaEvent from simulators.ursina.ursina_config import UrsinaConfig import ursina from ursina import camera, time, Vec3, application class BodiesSizeSim(UniverseSimScenes): def __init__(self): self.D = AU / 30000 # earth1 = Earth("地球1", init_position=[0, 0, 0], rotate_angle=-23.44) self.earth = Earth("地球", texture="earth2.jpg", rotate_angle=0, init_position=[3 * self.D, self.D, self.D]) self.bodies = [ Pluto(name="冥王星", init_position=[-4 * self.D, 0, 0]), # Europa(name="木卫二", init_position=[-3 * self.D, 0, 0]), Moon("月球", init_position=[-3 * self.D, 0, 0]), Io(name="木卫一", init_position=[-2 * self.D, 0, 0]), # Callisto(name="木卫四", init_position=[-1 * self.D, 0, 0]), # Ganymede(name="木卫三", init_position=[-self.D, 0, 0]), Mercury(name="水星", init_position=[-0.5*self.D, 0, 0]), Mars(name="火星", init_position=[-4 * self.D, self.D, self.D]), Venus(name="金星", init_position=[-self.D, self.D, self.D]), self.earth, # Earth("地球", texture="earth2.jpg", rotate_angle=0, init_position=[3 * self.D, self.D, self.D]), Uranus(name="天王星", init_position=[-6 * self.D, 5 * self.D, 5 * self.D]), Neptune(name="海王星", init_position=[6 * self.D, 5 * self.D, 5 * self.D]), Saturn(name="土星", init_position=[-20 * self.D, 11 * self.D, 30 * self.D]), # .show_rings(False), Jupiter(name="木星", texture='jupiter_hd.jpg', init_position=[25 * self.D, 14 * self.D, 25 * self.D]), Sun(name="太阳", init_position=[70 * self.D, 70 * self.D, 250 * self.D]), Sirius(name="天狼星A", init_position=[-90 * self.D, 120 * self.D, 450 * self.D]), Alcyone(name="昴宿六", init_position=[-900 * self.D, 1200 * self.D, 1200 * self.D]), # 质量倍数 6 半径倍数 9.5 Arcturus(name="大角星", init_position=[2000 * self.D, 3000 * self.D, 4000 * self.D]), # 质量倍数 1.1 半径倍数 25.7 Aldebaran(name="毕宿五", init_position=[-5000 * self.D, 4000 * self.D, 9000 * self.D]), # 质量倍数 1.16 半径倍数 44.13 Rigel(name="参宿七", init_position=[9000 * self.D, 8000 * self.D, 13000 * self.D]), # 质量倍数 18 半径倍数 78 # # YCanumVenaticorum(name="猎犬座Y", init_position=[-90*self.D, 120*self.D, 450*self.D]), # 质量倍数 3.0 半径倍数 215 EtaCarinae(name="海山二", init_position=[-15000 * self.D, 28000 * self.D, 45000 * self.D]), # 质量倍数 125 半径倍数 278 # # Antares(name="心宿二", init_position=[-90*self.D, 120*self.D, 450*self.D]), # 质量倍数 15 半径倍数 680 CarinaeV382(name="船底座V382", init_position=[35000 * self.D, 70000 * self.D, 150000 * self.D]), # 质量倍数 39 半径倍数 747 # # Betelgeuse(name="参宿四", init_position=[-90*self.D, 120*self.D, 450*self.D]), # 质量倍数 19 半径倍数 1180 VYCanisMajoris(name="大犬座VY", init_position=[-85000 * self.D, 140000 * self.D, 360000 * self.D]), # 质量倍数 30 半径倍数 1400 # # UYScuti(name="盾牌座 UY", init_position=[-85000*self.D, 140000*self.D, 360000*self.D]), # 盾牌座 UY 质量倍数 10 半径倍数 1708 Stephenson_2_18(name="史蒂文森2-18", init_position=[95000 * self.D, 200000 * self.D, 800000 * self.D]) # 史蒂文森2-18 质量倍数 40.0 半径倍数 2150 ] for idx, body in enumerate(self.bodies): # if body.rotation_speed == 0: body.rotation_speed = 10 body.init_velocity = [0, 0, 0] body.text_scale = 3 body.ignore_mass = True def on_ready(self): # 运行前触发 # 为了较好的立体效果,可以增加太阳光线,光线直射地球(target=earth) create_directional_light(position=([-5e2, -5e2, -5e4]), light_num=3, target=self.bodies[0]) camera.clip_plane_near = 0.001 camera.clip_plane_far = 50000000 camera.fov = 60 application.time_scale = 0.0001 sky = create_sphere_sky(scale=100000) # sky.alpha = 0.5 # sky.rotation_y = -90 sky.rotation_x = 200 # sky.rotation_z = 200 for idx, body in enumerate(self.bodies): if idx > 6: body.planet.enabled = False pass # for idx, body in enumerate(self.bodies): # if idx <= len(body_rotation_y) - 1: # body.planet.rotation_y = body_rotation_y[idx] # interval = 5 def camera_move(self, time_data): """ 摄像机移动控制 @param dt: @return: """ from ursina import distance # 摄像机移动控制数据 camera_move_infos = [ # 条件:年份 # 移动的信息: # 按坐标系方向移动 x:右+左-, y:升+降-, z:前+(接近太阳)后-(远离太阳) # 以摄像机视角移动 f:前 b:后 l:左 r:右 u:上 d:下 (0, {"r": 0.00008}), (8, {"b": 0.0005, "u": 0.0001}), (10, {"b": 0.005, "u": 0.001}), (20, {"b": 0.5, "u": 0.1}), (30, {"b": 1, "u": 0.2}), (1000000, {"b": 0.02}), (2000000, {}), # (2000, {"exit": True}), # (1989, {"z": -8, "f": -5}), # (1993, {"z": -8, "f": -3}), # (1995, {"z": -8}), # (2000, {"z": -8, "y": -0.2}), # (2013, {}), # (2048, {"f": 3}), # (2062, {"y": -3}), # (2063, {"y": -10, "z": 2}), # (2181, {}), # (2082, {"exit": True}) (250, {"exit": True}), ] def cond_cb(ps): return ps["next_cond"] > time_data.total_hours >= ps["cond"] d_earth = distance(camera.position, self.earth.planet.position) distance_ctrl_infos = [ (0.018, [7, 10]), (0.025, [10, 12]), (0.08, [12, 14]), (0.3, [14, 15]), (0.5, [15, 16]), (100.05, None) ] for i, ctrl_info in enumerate(distance_ctrl_infos[:-1]): d1, ctrl_info1 = ctrl_info d2, ctrl_info2 = distance_ctrl_infos[i + 1] if ctrl_info1 is None: continue if d1 < d_earth <= d2: for idx, body in enumerate(self.bodies[ctrl_info1[0]:ctrl_info1[1]]): if body.planet.enabled: continue body.planet.alpha = 0.0 body.planet.enabled = True self.set_alpha_animation(body, 0.0, 1.0, 0.1) print("d", d_earth) # if d_earth > 0.025: # for idx, body in enumerate(self.bodies[7:10]): # if body.planet.enabled: # continue # body.planet.alpha = 0.0 # body.planet.enabled = True # self.set_alpha_animation(body, 0.0, 1.0, 0.01) camera_move_control(camera_move_infos, cond_cb=cond_cb, value_conv=self.s_f) def set_alpha_animation(self, body, begin_alpha, end_alpha, interval, is_destroy=False): from ursina import destroy if hasattr(body, "planet"): planet = body.planet else: planet = body planet.alpha = begin_alpha if begin_alpha > end_alpha: interval = -abs(interval) / self.record_rate else: interval = abs(interval) / self.record_rate origin_update = planet.update def alpha_animation(): from ursina import camera, Vec4 origin_update() alpha = planet.alpha alpha += interval if (interval > 0 and alpha >= end_alpha) or (interval < 0 and alpha <= end_alpha): alpha = end_alpha planet.update = origin_update planet.enabled = (alpha > 0) planet.alpha = alpha if is_destroy and not planet.enabled: destroy(planet) # planet.color = Vec4(planet.color[0], planet.color[1], planet.color[2], alpha) # print(body, planet.alpha, planet.rotation_x, planet.rotation_y, planet.rotation_z) planet.update = alpha_animation def s_f(self, value=1): if value == 0: return 0 return get_run_speed_factor() * value def on_timer_changed(self, time_data: TimeData): self.camera_move(time_data) def run(self): # 运行中,每时每刻都会触发 on_timer_changed UrsinaEvent.on_timer_changed_subscription(self.on_timer_changed) # 运行前会触发 on_ready UrsinaEvent.on_ready_subscription(self.on_ready) # 使用 ursina 查看的运行效果 # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 # position = 左-右+、上+下-、前+后- ursina_run(self.bodies, SECONDS_PER_HOUR / 2, position=[-2e4, 0, -0.8e4], # position=[0, 0, -5e4], # position=[0, 2e4, -15e4], # 海王星 # position=[0, 2e4, -35e4], # 木星 # position=[0, 35e4, -150e4], # 太阳 # position=[0, 50e4, -250e4], # 天狼星 # position=[0, 500e4, -2400e4], # 昴宿六 # position=[0, 1500e4, -5500e4], # 大角星 # position=[0, 2500e4, -10000e4], # 毕宿五 # position=[0, 5000e4, -20000e4], # 参宿七 # position=[0, 15000e4, -55000e4], # 海山二 # position=[0, 38000e4, -150000e4], # 船底座V382 # position=[0, 80000e4, -300000e4], # 盾牌座 UY # position=[0, 70000e4, -280000e4], # 史蒂文森2-18 cosmic_bg='', show_name=True, show_control_info=False, show_exit_button=False, show_camera_info=False, show_grid=False, # view_closely=True, show_timer=True, timer_enabled=True) if __name__ == '__main__': BodiesSizeSim().run()