# -*- coding:utf-8 -*- # title :太阳系中消失的行星 # description :太阳系中消失的行星 # author :Python超人 # date :2023-12-05 # link :https://gitcode.net/pythoncr/ # python_version :3.9 # ============================================================================== from bodies import Sun, Mercury, Venus, Earth, Mars, Moon, Ceres, Jupiter, Saturn, Uranus, Neptune, Pluto, Asteroids from common.consts import SECONDS_PER_WEEK, SECONDS_PER_DAY, SECONDS_PER_MONTH, SECONDS_PER_YEAR, AU from sim_scenes.func import mayavi_run, ursina_run, create_sphere_sky from sim_scenes.universe_sim_scenes import UniverseSimScenes from simulators.func import ext_fun_for_method from simulators.ursina.ursina_event import UrsinaEvent if __name__ == '__main__': sun = Sun(size_scale=5e2).set_resolution(60) # 太阳放大 500 倍 sun.glows = (30, 1.005, 0.03) asteroids = Asteroids(size_scale=1.08e2, parent=sun) # 小行星模拟(仅 ursina 模拟器支持) # 环状星群带(inner_radius, outer_radius, subdivisions) # inner_radius:内圆半径 outer_radius:外圆半径,subdivisions:细分数,控制圆环的细节和精度 asteroids.torus_zone = 4.7, 5.5, 64 moon = Moon(size_scale=3e3, init_position=[0, 0, (0.4 + 2.4) * AU], distance_scale=1.8) ceres = Ceres(size_scale=3e3, distance_scale=1.7) earth = Earth(size_scale=3e3, distance_scale=3.8) mars = Mars(size_scale=3e3, distance_scale=2.9) jupiter = Jupiter(size_scale=0.68e3, distance_scale=1.15) saturn = Saturn(size_scale=0.68e3, distance_scale=0.74) bodies = [ sun, Mercury(size_scale=3e3, distance_scale=7), # 水星放大 4000 倍 Venus(size_scale=3e3, distance_scale=4.3), # 金星放大 4000 倍 earth, # 地球放大 4000 倍 mars, # 火星放大 4000 倍 asteroids, moon, ceres, # Earth(size_scale=3e3, init_position=[0, 0, (2.17) * AU]), # 地球放大 4000 倍 # Earth(size_scale=3e3, init_position=[0, 0, (3.64) * AU]), # 地球放大 4000 倍 jupiter, # 木星放大 680 倍 saturn, # 土星放大 680 倍 Uranus(size_scale=0.8e3, distance_scale=0.42), # 天王星放大 800 倍 Neptune(size_scale=1e3, distance_scale=0.3), # 海王星放大 1000 倍 ] # 水星 0.4AU # 金星 0.4+0.3 AU # 地球 0.4+0.6 AU # 火星 0.4+1.2 AU # 木星 0.4+4.8 AU # 土星 0.4+9.6 AU # 天王星 0.4+19.2 AU # d = (n+4)/10 # an = 0.4+0.3×(2n-2) planet_no = -1 for idx, body in enumerate(bodies): if isinstance(body, Asteroids): continue body.rotation_speed = 0 planet_no += 1 # body.init_velocity = [0, 0, 0] # an = 0.4 + 0.3 * pow(2,idx) # an = (idx+4)/10 # 其中k=0,1,2,4,8,16,32,64,128 (0以后数字为2的2次方) # 行星 公式推得值 实测值 # 金星 0.7 0.72 # 地球 1 1 # 火星 1.6 1.52 # 谷神星 2.8 2.9 [1] # 木星 5.2 5.2 # 土星 10 9.54 # 天王星 19.6 19.18 # 海王星 38.8 30.06 # 冥王星 77.2 39.44 # 提丢斯-波得定则 # https://baike.baidu.com/item/%E6%8F%90%E4%B8%A2%E6%96%AF-%E6%B3%A2%E5%BE%97%E5%AE%9A%E5%88%99/859407 # 小行星 2.17-3.64天文单位 if planet_no == 0: continue elif planet_no == 1: an = 0.4 else: an = 0.4 + 0.3 * pow(2, planet_no - 2) print(body.name, an, body.position[2] / AU) def on_ready(): """ 事件绑定后,模拟器运行前会触发 @return: """ from ursina import camera, Vec3 # 创建天空 create_sphere_sky(scale=20000, rotation_x=0, rotation_y=80) camera.clip_plane_near = 0.1 camera.clip_plane_far = 1000000 camera.look_at(jupiter.planet) # camera.look_at(sun.planet) camera.rotation_z -= 90 # UniverseSimScenes.show_grid_axises() asteroids.planet.enabled = False moon.planet.enabled = False ceres.planet.enabled = False def set_alpha_animation(body, begin_alpha, end_alpha, interval): planet = body.planet planet.alpha = begin_alpha if begin_alpha > end_alpha: interval = -abs(interval) else: interval = abs(interval) 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 # planet.color = Vec4(planet.color[0], planet.color[1], planet.color[2], alpha) print(planet.alpha) planet.update = alpha_animation # ext_fun_for_method(planet, after_run_fun=alpha_animation) # # def after_ready(): # from ursina import camera, Vec3 # camera.position = Vec3(0,149.60,-665.76) # camera.world_position = Vec3(-14.71,-98.38,0) # def on_timer_changed(time_data): from ursina import camera, Vec3, distance import math # print(time_data.years) if time_data.years > 1 and not hasattr(asteroids, "years_1"): set_alpha_animation(asteroids, 0.0, 1.0, 0.01) setattr(asteroids, "years_1", True) elif time_data.years > 4 and not hasattr(asteroids, "years_5"): set_alpha_animation(asteroids, 1.0, 0.0, 0.01) setattr(asteroids, "years_5", True) elif time_data.years > 6 and not hasattr(moon, "years_6"): moon.planet.look_at(mars.planet) moon.planet.update = lambda: None set_alpha_animation(moon, 0.0, 1.0, 0.005) setattr(moon, "years_6", True) elif time_data.years > 8 and not hasattr(asteroids, "years_8"): set_alpha_animation(asteroids, 0.0, 1.0, 0.01) setattr(asteroids, "years_8", True) if time_data.years > 8 and not hasattr(moon, "years_8"): moon.planet.look_at(mars.planet) radius = 12 d = distance(moon.planet, mars.planet.position) if d > 12: moon.planet.position += moon.planet.forward * 0.1 else: if not hasattr(mars, "moon_angle"): setattr(mars, "moon_angle", 90) moon_angle = getattr(mars, "moon_angle") x = mars.planet.x + radius * math.cos(moon_angle) z = mars.planet.z + radius * math.sin(moon_angle) moon.planet.position = (x, 0, z) setattr(mars, "moon_angle", moon_angle + 0.08) if moon_angle >= 110: setattr(moon, "years_8", True) print("moon_angle",moon_angle) elif hasattr(mars, "moon_angle") and not hasattr(moon, "earth_rotation"): earth_target = earth.planet.main_entity moon.planet.look_at(earth_target) radius = 15 d = distance(moon.planet.position, earth_target.position) if d > 15: moon.planet.position += moon.planet.forward * 0.1 else: if not hasattr(earth, "moon_angle"): setattr(earth, "moon_angle", 90) moon_angle = getattr(earth, "moon_angle") x = earth_target.x + radius * math.cos(moon_angle) z = earth_target.z + radius * math.sin(moon_angle) moon.planet.position = (x, 0, z) setattr(earth, "moon_angle", moon_angle + 0.08) if moon_angle >= 360 * 2 + 90: setattr(moon, "earth_rotation", True) print("moon_angle", moon_angle) # moon.planet.world_rotation_z = 90 # moon.planet.position += moon.planet.right * 0.1 # setattr(moon, "years_8", True) # elif time_data.years > 15 and not hasattr(moon, "years_15"): # set_alpha_animation(moon, 1.0, 0.0, 0.05) # setattr(moon, "years_15", True) # UniverseSimScenes.set_window_size((1920, 1079), False) # 运行前会触发 on_ready UrsinaEvent.on_ready_subscription(on_ready) # UrsinaEvent.after_ready_subscription(after_ready) UrsinaEvent.on_timer_changed_subscription(on_timer_changed) # 使用 ursina 查看的运行效果 # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 # position = 左-右+、上+下-、前+后- ursina_run(bodies, SECONDS_PER_YEAR, gravity_works=False, show_exit_button=False, show_control_info=False, show_camera_info=False, # position=(0, 2 * AU, -11 * AU), # position=(0, 20 * AU, 10 * AU), position=(5.5 * AU, AU, 5 * AU), timer_enabled=True, show_timer=True, cosmic_bg='', show_grid=False)