diff --git a/objs/textures/caustic.jpg b/objs/textures/caustic.jpg index 0900812dfd31ff588907649e8bcb87eff9c4ed88..3602644d0f6029a734e2b65d0b45dce8028f1c89 100644 Binary files a/objs/textures/caustic.jpg and b/objs/textures/caustic.jpg differ diff --git a/objs/textures/wave.jpg b/objs/textures/wave.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8bacf9a0f5f1dadf049a985971a39c9d61e463f8 Binary files /dev/null and b/objs/textures/wave.jpg differ diff --git a/sim_lab/two_way_foil_lab.py b/sim_lab/two_way_foil_lab.py new file mode 100644 index 0000000000000000000000000000000000000000..93793b56edc4c0fe7a6195a94146a9cb6d6c1ed3 --- /dev/null +++ b/sim_lab/two_way_foil_lab.py @@ -0,0 +1,298 @@ +# -*- coding:utf-8 -*- +# title :三体二向箔场景模拟 +# description :三体二向箔场景模拟 +# author :Python超人 +# date :2023-10-11 +# link :https://gitcode.net/pythoncr/ +# python_version :3.9 +# ============================================================================== + + +from bodies import Sun, Earth, Moon +from objs import CoreValagaClas, SciFiBomber, WaterDrop, QuadObj, CircleObj +from common.consts import AU, SECONDS_PER_DAY, SECONDS_PER_WEEK, SECONDS_PER_MONTH +from sim_scenes.func import ursina_run, camera_look_at, create_main_entity, two_bodies_colliding +from simulators.ursina.entities.body_timer import TimeData +from simulators.ursina.entities.entity_utils import create_directional_light, create_rings +from simulators.ursina.ursina_config import UrsinaConfig +from simulators.ursina.ursina_event import UrsinaEvent +from ursina import camera, application + +from bodies import Sun, Mercury, Venus, Earth, Mars, 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 simulators.ursina.ursina_event import UrsinaEvent + + +def get_init_pos_vels(): + init_pos_vels = {} + # init_pos_vels['sun'] = {} + # init_pos_vels['sun']['pos'] = [120062.8111, -462734.9565, -198328.7512] + # init_pos_vels['sun']['vel'] = [0.0093, 0.0037, 0.0014] + # init_pos_vels['mercury'] = {} + # init_pos_vels['mercury']['pos'] = [-27459444.3141, 33659309.8266, 20887619.1358] + # init_pos_vels['mercury']['vel'] = [-49.8268, -24.7415, -8.0569] + # init_pos_vels['venus'] = {} + # init_pos_vels['venus']['pos'] = [21823958.6720, -97202911.8077, -45109059.0044] + # init_pos_vels['venus']['vel'] = [34.0912, 7.0463, 1.0154] + # init_pos_vels['earth'] = {} + # init_pos_vels['earth']['pos'] = [-25983996.5057, 132369339.0025, 57373518.2429] + # init_pos_vels['earth']['vel'] = [-29.7869, -4.9606, -2.1489] + # init_pos_vels['mars'] = {} + # init_pos_vels['mars']['pos'] = [-230623216.7918, -71477306.3132, -26561224.6080] + # init_pos_vels['mars']['vel'] = [8.4564, -18.9614, -8.9250] + # init_pos_vels['jupiter'] = {} + # init_pos_vels['jupiter']['pos'] = [-357712686.7572, 637570826.6050, 281973598.8065] + # init_pos_vels['jupiter']['vel'] = [-11.7897, -5.0252, -1.8671] + # init_pos_vels['saturn'] = {} + # init_pos_vels['saturn']['pos'] = [713384516.7012, -1202372203.9542, -527442445.4970] + # init_pos_vels['saturn']['vel'] = [7.9649, 4.3679, 1.4610] + # init_pos_vels['uranus'] = {} + # init_pos_vels['uranus']['pos'] = [-2666283945.3730, 544495773.6564, 276202868.3064] + # init_pos_vels['uranus']['vel'] = [-1.5476, -6.3725, -2.7691] + # init_pos_vels['neptune'] = {} + # init_pos_vels['neptune']['pos'] = [2602697275.5219, 3374419276.7397, 1316379531.2695] + # init_pos_vels['neptune']['vel'] = [-4.4365, 2.9291, 1.3095] + + init_pos_vels['sun'] = {} + init_pos_vels['sun']['pos'] = [-4638653.0000, 0.0000, 1314332.6250] + init_pos_vels['sun']['vel'] = [-0.0165, 0.0000, -0.0097] + init_pos_vels['mercury'] = {} + init_pos_vels['mercury']['pos'] = [-54412616.0000, 0.0000, 31280100.0000] + init_pos_vels['mercury']['vel'] = [-25.2667, 0.0000, -40.0561] + init_pos_vels['venus'] = {} + init_pos_vels['venus']['pos'] = [-32341672.0000, 0.0000, -99861352.0000] + init_pos_vels['venus']['vel'] = [34.3770, 0.0000, -10.6676] + init_pos_vels['earth'] = {} + init_pos_vels['earth']['pos'] = [140427392.0000, 0.0000, 45724572.0000] + init_pos_vels['earth']['vel'] = [-8.1280, 0.0000, 28.2277] + init_pos_vels['mars'] = {} + init_pos_vels['mars']['pos'] = [218751648.0000, 0.0000, -45263688.0000] + init_pos_vels['mars']['vel'] = [5.2205, 0.0000, 23.4601] + init_pos_vels['asteroids'] = {} + init_pos_vels['asteroids']['pos'] = [0.0000, 0.0000, 0.0000] + init_pos_vels['asteroids']['vel'] = [0.0000, 0.0000, 0.0000] + init_pos_vels['jupiter'] = {} + init_pos_vels['jupiter']['pos'] = [769445760.0000, 0.0000, 2017638.5000] + init_pos_vels['jupiter']['vel'] = [0.0389, 0.0000, 13.0879] + init_pos_vels['saturn'] = {} + init_pos_vels['saturn']['pos'] = [-1330536704.0000, 0.0000, -454165280.0000] + init_pos_vels['saturn']['vel'] = [3.2189, 0.0000, -9.1974] + init_pos_vels['uranus'] = {} + init_pos_vels['uranus']['pos'] = [-1757163648.0000, 0.0000, 2272503808.0000] + init_pos_vels['uranus']['vel'] = [-5.3918, 0.0000, -4.1634] + init_pos_vels['neptune'] = {} + init_pos_vels['neptune']['pos'] = [-1480893824.0000, 0.0000, 4351772160.0000] + init_pos_vels['neptune']['vel'] = [-5.1466, 0.0000, -1.7189] + init_pos_vels['pluto'] = {} + init_pos_vels['pluto']['pos'] = [-1293909504.0000, 0.0000, 5770579968.0000] + init_pos_vels['pluto']['vel'] = [-4.5847, 0.0000, -1.0475] + + return init_pos_vels + + +if __name__ == '__main__': + """ + 三体二向箔场景模拟 + """ + + # region 构建太阳系 + sun = Sun(size_scale=0.8e2) + bodies = [ + sun, # 太阳放大 80 倍 + Mercury(size_scale=4e3, distance_scale=1.3), # 水星放大 4000 倍,距离放大 1.3 倍 + Venus(size_scale=4e3, distance_scale=1.3), # 金星放大 4000 倍,距离放大 1.3 倍 + Earth(size_scale=4e3, distance_scale=1.3), # 地球放大 4000 倍,距离放大 1.3 倍 + Mars(size_scale=4e3, distance_scale=1.2), # 火星放大 4000 倍,距离放大 1.2 倍 + Asteroids(size_scale=1e2, parent=sun), # 小行星模拟(仅 ursina 模拟器支持) + Jupiter(size_scale=0.68e3, distance_scale=0.72), # 木星放大 680 倍,距离缩小到真实距离的 0.72 + Saturn(size_scale=0.68e3, distance_scale=0.52), # 土星放大 680 倍,距离缩小到真实距离的 0.52 + Uranus(size_scale=0.8e3, distance_scale=0.36), # 天王星放大 800 倍,距离缩小到真实距离的 0.36 + Neptune(size_scale=1e3, distance_scale=0.27), # 海王星放大 1000 倍,距离缩小到真实距离的 0.27 + Pluto(size_scale=10e3, distance_scale=0.23), # 冥王星放大 10000 倍,距离缩小到真实距离的 0.23(从太阳系的行星中排除) + ] + # endregion + + init_pos_vels = get_init_pos_vels() + + for body in bodies: + pos_vels = init_pos_vels.get(type(body).__name__.lower(), None) + if pos_vels is None: + continue + body.init_position = pos_vels['pos'] + body.init_velocity = pos_vels['vel'] + + two_way_foil = QuadObj(texture='wave.jpg', size_scale=4e7, + init_velocity=[0, 0, 100], + init_position=[0, 0, -10 * AU]) \ + .set_light_disable(True).set_ignore_gravity(True) + + two_way_foil_circle = CircleObj(texture=two_way_foil.texture, + size_scale=two_way_foil.size_scale * 2, + ) \ + .set_light_disable(True).set_ignore_gravity(True) + + three_dim_bodies = [] + two_dim_bodies = [] + + + def create_two_dim(body): + body_2 = CircleObj(texture=body.texture, + size_scale=body.diameter * body.size_scale, + distance_scale=body.distance_scale, + init_position=body.position) \ + .set_light_disable(True).set_ignore_gravity(True) + + body.two_dim = body_2 + body_2.three_dim = body + return body_2 + + + for body in bodies: + two_dim_body = create_two_dim(body) + three_dim_bodies.append(body) + two_dim_bodies.append(two_dim_body) + + bodies.append(two_way_foil) + bodies.append(two_way_foil_circle) + + for body in two_dim_bodies: + bodies.append(body) + + + def on_ready(): + """ + 事件绑定后,模拟器运行前会触发 + @return: + """ + # 创建天空 + # camera.clip_plane_near = 0.1 + camera.clip_plane_far = 1000000 + create_sphere_sky(scale=200000) + application.time_scale = 3 + for body in two_dim_bodies: + body.planet.enabled = False + model = body.planet.model + if body.three_dim.has_rings: + rings = create_rings(body.planet) + rings.scale *= 2e10 + + two_way_foil_circle.planet.rotation_x = 90 + two_way_foil_circle.planet.enabled = False + for b in two_dim_bodies: + b.planet.rotation_x = 90 + + + current_stage = None + + + def stage_01(): + """ + 二向箔飞向太阳 + @return: + """ + global current_stage + if two_bodies_colliding(two_way_foil, sun): + sun.planet.enabled = False + sun.two_dim.planet.enabled = True + sun.two_dim.planet.x += 100000 + # two_way_foil.explode(sun) + two_way_foil.planet.enabled = False + two_way_foil_circle.planet.alpha = 0.7 + two_way_foil_circle.planet.enabled = True + current_stage = stage_02 + + + def blink(body): + return + if not hasattr(body, "blink_d"): + body.blink_d = 1 + body.blink_v = 1 + + if body.blink_d > 0: + body.blink_v -= 0.05 + body.planet.alpha = body.blink_v + if body.blink_v <= 0.7: + body.blink_d = -1 + elif body.blink_d < 0: + body.blink_v += 0.05 + body.planet.alpha = body.blink_v + if body.blink_v >= 1: + body.blink_d = 1 + + + def stage_02(): + """ + + @return: + """ + global current_stage + sun.two_dim.planet.init_scale += 0.05 + two_way_foil_circle.planet.init_scale += 0.8 + blink(sun.two_dim) + for b in three_dim_bodies: + if two_bodies_colliding(two_way_foil_circle, b): + b.planet.enabled = False + b.two_dim.planet.enabled = True + if b.two_dim.planet.enabled: + b.two_dim.planet.init_scale += 0.05 + blink(b.two_dim) + two_way_foil_circle.planet.rotation_z += 0.2 + + + current_stage = stage_01 + + + def on_timer_changed(time_data): + two_way_foil.planet.rotation_x += 1 + two_way_foil.planet.rotation_y += 10 + current_stage() + # if sun.two_dim.planet.enabled: + # sun.two_dim.planet.init_scale += 1.1 + # for b in three_dim_bodies: + # if two_bodies_colliding(sun.two_dim, b): + # b.planet.enabled = False + # b.two_dim.planet.enabled = True + # if b.two_dim.planet.enabled: + # b.two_dim.planet.init_scale += 1.1 + # else: + # if two_bodies_colliding(two_way_foil, sun): + # sun.planet.enabled = False + # sun.two_dim.planet.enabled = True + + # for b in three_dim_bodies: + # b.planet.enabled = False + init_pos_vels_info = "" + for b in two_dim_bodies: + # b.planet.rotation_x = 90 + b.init_position = b.three_dim.position + pos, vel = b.three_dim.position, b.three_dim.velocity + t_name = type(b.three_dim).__name__.lower() + init_pos_vels_info += f" init_pos_vels['{t_name}'] = {{}}" + init_pos_vels_info += f" init_pos_vels['{t_name}']['pos'] = [%.4f,%.4f,%.4f]\n" % ( + pos[0], pos[1], pos[2]) + init_pos_vels_info += f" init_pos_vels['{t_name}']['vel'] = [%.4f,%.4f,%.4f]\n" % ( + vel[0], vel[1], vel[2]) + # init_pos_vels['sun'] = {} + # init_pos_vels['sun']['pos'] = [120062.8111, -462734.9565, -198328.7512] + # init_pos_vels['sun']['vel'] = [0.0093, 0.0037, 0.0014] + + # print(b.planet.position, b.three_dim.planet.position) + # print("----------------------------------------------") + # print(init_pos_vels_info) + + + # 订阅事件后,上面2个函数功能才会起作用 + # 运行中,每时每刻都会触发 on_timer_changed + UrsinaEvent.on_timer_changed_subscription(on_timer_changed) + # 运行前会触发 on_ready + UrsinaEvent.on_ready_subscription(on_ready) + # 使用 ursina 查看的运行效果 + # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 + # position = 左-右+、上+下-、前+后- + ursina_run(bodies, SECONDS_PER_MONTH / 2, position=(0, 2 * AU, -11 * AU), + cosmic_bg='', + show_camera_info=False, + show_control_info=False, + timer_enabled=True, + show_grid=False) diff --git a/sim_scenes/tri_bodies/two_way_foil.py b/sim_scenes/tri_bodies/two_way_foil.py index da4a5f3636ede00289c82054b0a8072cddde1008..845cc40dcf1d853f14d5384767c6dbd8291dfec0 100644 --- a/sim_scenes/tri_bodies/two_way_foil.py +++ b/sim_scenes/tri_bodies/two_way_foil.py @@ -16,7 +16,7 @@ from simulators.ursina.entities.body_timer import TimeData from simulators.ursina.entities.entity_utils import create_directional_light, create_rings from simulators.ursina.ursina_config import UrsinaConfig from simulators.ursina.ursina_event import UrsinaEvent -from ursina import camera +from ursina import camera, application from bodies import Sun, Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto, Asteroids from common.consts import SECONDS_PER_WEEK, SECONDS_PER_DAY, SECONDS_PER_MONTH, SECONDS_PER_YEAR, AU @@ -24,143 +24,121 @@ from sim_scenes.func import mayavi_run, ursina_run, create_sphere_sky from simulators.ursina.ursina_event import UrsinaEvent -def get_init_pos_vels(): - init_pos_vels = {} - # init_pos_vels['sun'] = {} - # init_pos_vels['sun']['pos'] = [120062.8111, -462734.9565, -198328.7512] - # init_pos_vels['sun']['vel'] = [0.0093, 0.0037, 0.0014] - # init_pos_vels['mercury'] = {} - # init_pos_vels['mercury']['pos'] = [-27459444.3141, 33659309.8266, 20887619.1358] - # init_pos_vels['mercury']['vel'] = [-49.8268, -24.7415, -8.0569] - # init_pos_vels['venus'] = {} - # init_pos_vels['venus']['pos'] = [21823958.6720, -97202911.8077, -45109059.0044] - # init_pos_vels['venus']['vel'] = [34.0912, 7.0463, 1.0154] - # init_pos_vels['earth'] = {} - # init_pos_vels['earth']['pos'] = [-25983996.5057, 132369339.0025, 57373518.2429] - # init_pos_vels['earth']['vel'] = [-29.7869, -4.9606, -2.1489] - # init_pos_vels['mars'] = {} - # init_pos_vels['mars']['pos'] = [-230623216.7918, -71477306.3132, -26561224.6080] - # init_pos_vels['mars']['vel'] = [8.4564, -18.9614, -8.9250] - # init_pos_vels['jupiter'] = {} - # init_pos_vels['jupiter']['pos'] = [-357712686.7572, 637570826.6050, 281973598.8065] - # init_pos_vels['jupiter']['vel'] = [-11.7897, -5.0252, -1.8671] - # init_pos_vels['saturn'] = {} - # init_pos_vels['saturn']['pos'] = [713384516.7012, -1202372203.9542, -527442445.4970] - # init_pos_vels['saturn']['vel'] = [7.9649, 4.3679, 1.4610] - # init_pos_vels['uranus'] = {} - # init_pos_vels['uranus']['pos'] = [-2666283945.3730, 544495773.6564, 276202868.3064] - # init_pos_vels['uranus']['vel'] = [-1.5476, -6.3725, -2.7691] - # init_pos_vels['neptune'] = {} - # init_pos_vels['neptune']['pos'] = [2602697275.5219, 3374419276.7397, 1316379531.2695] - # init_pos_vels['neptune']['vel'] = [-4.4365, 2.9291, 1.3095] - - init_pos_vels['sun'] = {} - init_pos_vels['sun']['pos'] = [-4638653.0000, 0.0000, 1314332.6250] - init_pos_vels['sun']['vel'] = [-0.0165, 0.0000, -0.0097] - init_pos_vels['mercury'] = {} - init_pos_vels['mercury']['pos'] = [-54412616.0000, 0.0000, 31280100.0000] - init_pos_vels['mercury']['vel'] = [-25.2667, 0.0000, -40.0561] - init_pos_vels['venus'] = {} - init_pos_vels['venus']['pos'] = [-32341672.0000, 0.0000, -99861352.0000] - init_pos_vels['venus']['vel'] = [34.3770, 0.0000, -10.6676] - init_pos_vels['earth'] = {} - init_pos_vels['earth']['pos'] = [140427392.0000, 0.0000, 45724572.0000] - init_pos_vels['earth']['vel'] = [-8.1280, 0.0000, 28.2277] - init_pos_vels['mars'] = {} - init_pos_vels['mars']['pos'] = [218751648.0000, 0.0000, -45263688.0000] - init_pos_vels['mars']['vel'] = [5.2205, 0.0000, 23.4601] - init_pos_vels['asteroids'] = {} - init_pos_vels['asteroids']['pos'] = [0.0000, 0.0000, 0.0000] - init_pos_vels['asteroids']['vel'] = [0.0000, 0.0000, 0.0000] - init_pos_vels['jupiter'] = {} - init_pos_vels['jupiter']['pos'] = [769445760.0000, 0.0000, 2017638.5000] - init_pos_vels['jupiter']['vel'] = [0.0389, 0.0000, 13.0879] - init_pos_vels['saturn'] = {} - init_pos_vels['saturn']['pos'] = [-1330536704.0000, 0.0000, -454165280.0000] - init_pos_vels['saturn']['vel'] = [3.2189, 0.0000, -9.1974] - init_pos_vels['uranus'] = {} - init_pos_vels['uranus']['pos'] = [-1757163648.0000, 0.0000, 2272503808.0000] - init_pos_vels['uranus']['vel'] = [-5.3918, 0.0000, -4.1634] - init_pos_vels['neptune'] = {} - init_pos_vels['neptune']['pos'] = [-1480893824.0000, 0.0000, 4351772160.0000] - init_pos_vels['neptune']['vel'] = [-5.1466, 0.0000, -1.7189] - init_pos_vels['pluto'] = {} - init_pos_vels['pluto']['pos'] = [-1293909504.0000, 0.0000, 5770579968.0000] - init_pos_vels['pluto']['vel'] = [-4.5847, 0.0000, -1.0475] - - return init_pos_vels - - -if __name__ == '__main__': +class TwoWayFoilSim: """ 三体二向箔场景模拟 """ - # region 构建太阳系 - sun = Sun(size_scale=0.8e2) - bodies = [ - sun, # 太阳放大 80 倍 - Mercury(size_scale=4e3, distance_scale=1.3), # 水星放大 4000 倍,距离放大 1.3 倍 - Venus(size_scale=4e3, distance_scale=1.3), # 金星放大 4000 倍,距离放大 1.3 倍 - Earth(size_scale=4e3, distance_scale=1.3), # 地球放大 4000 倍,距离放大 1.3 倍 - Mars(size_scale=4e3, distance_scale=1.2), # 火星放大 4000 倍,距离放大 1.2 倍 - Asteroids(size_scale=1e2, parent=sun), # 小行星模拟(仅 ursina 模拟器支持) - Jupiter(size_scale=0.68e3, distance_scale=0.72), # 木星放大 680 倍,距离缩小到真实距离的 0.72 - Saturn(size_scale=0.68e3, distance_scale=0.52), # 土星放大 680 倍,距离缩小到真实距离的 0.52 - Uranus(size_scale=0.8e3, distance_scale=0.36), # 天王星放大 800 倍,距离缩小到真实距离的 0.36 - Neptune(size_scale=1e3, distance_scale=0.27), # 海王星放大 1000 倍,距离缩小到真实距离的 0.27 - Pluto(size_scale=10e3, distance_scale=0.23), # 冥王星放大 10000 倍,距离缩小到真实距离的 0.23(从太阳系的行星中排除) - ] - # endregion - - init_pos_vels = get_init_pos_vels() - - for body in bodies: - pos_vels = init_pos_vels.get(type(body).__name__.lower(), None) - if pos_vels is None: - continue - body.init_position = pos_vels['pos'] - body.init_velocity = pos_vels['vel'] - - two_way_foil = QuadObj(texture='caustic.jpg', size_scale=4e7, - init_velocity=[0, 0, 100], - init_position=[0, 0, -10 * AU]) \ - .set_light_disable(True).set_ignore_gravity(True) - - two_way_foil_circle = CircleObj(texture=two_way_foil.texture, - size_scale=two_way_foil.size_scale * 2, - ) \ - .set_light_disable(True).set_ignore_gravity(True) - - three_dim_bodies = [] - two_dim_bodies = [] - + def __init__(self): + + self.three_dim_bodies = [] + self.two_dim_bodies = [] + self.current_stage = self.stage_01 + + def get_init_pos_vels(self): + init_pos_vels = {} + init_pos_vels['sun'] = {} + init_pos_vels['sun']['pos'] = [-4638653.0000, 0.0000, 1314332.6250] + init_pos_vels['sun']['vel'] = [-0.0165, 0.0000, -0.0097] + init_pos_vels['mercury'] = {} + init_pos_vels['mercury']['pos'] = [-54412616.0000, 0.0000, 31280100.0000] + init_pos_vels['mercury']['vel'] = [-25.2667, 0.0000, -40.0561] + init_pos_vels['venus'] = {} + init_pos_vels['venus']['pos'] = [-32341672.0000, 0.0000, -99861352.0000] + init_pos_vels['venus']['vel'] = [34.3770, 0.0000, -10.6676] + init_pos_vels['earth'] = {} + init_pos_vels['earth']['pos'] = [140427392.0000, 0.0000, 45724572.0000] + init_pos_vels['earth']['vel'] = [-8.1280, 0.0000, 28.2277] + init_pos_vels['mars'] = {} + init_pos_vels['mars']['pos'] = [218751648.0000, 0.0000, -45263688.0000] + init_pos_vels['mars']['vel'] = [5.2205, 0.0000, 23.4601] + init_pos_vels['asteroids'] = {} + init_pos_vels['asteroids']['pos'] = [0.0000, 0.0000, 0.0000] + init_pos_vels['asteroids']['vel'] = [0.0000, 0.0000, 0.0000] + init_pos_vels['jupiter'] = {} + init_pos_vels['jupiter']['pos'] = [769445760.0000, 0.0000, 2017638.5000] + init_pos_vels['jupiter']['vel'] = [0.0389, 0.0000, 13.0879] + init_pos_vels['saturn'] = {} + init_pos_vels['saturn']['pos'] = [-1330536704.0000, 0.0000, -454165280.0000] + init_pos_vels['saturn']['vel'] = [3.2189, 0.0000, -9.1974] + init_pos_vels['uranus'] = {} + init_pos_vels['uranus']['pos'] = [-1757163648.0000, 0.0000, 2272503808.0000] + init_pos_vels['uranus']['vel'] = [-5.3918, 0.0000, -4.1634] + init_pos_vels['neptune'] = {} + init_pos_vels['neptune']['pos'] = [-1480893824.0000, 0.0000, 4351772160.0000] + init_pos_vels['neptune']['vel'] = [-5.1466, 0.0000, -1.7189] + init_pos_vels['pluto'] = {} + init_pos_vels['pluto']['pos'] = [-1293909504.0000, 0.0000, 5770579968.0000] + init_pos_vels['pluto']['vel'] = [-4.5847, 0.0000, -1.0475] + + return init_pos_vels + + def build_solar_system(self): + # region 构建太阳系 + self.sun = Sun(size_scale=0.8e2) + self.bodies = [ + self.sun, # 太阳放大 80 倍 + Mercury(size_scale=4e3, distance_scale=1.3), # 水星放大 4000 倍,距离放大 1.3 倍 + Venus(size_scale=4e3, distance_scale=1.3), # 金星放大 4000 倍,距离放大 1.3 倍 + Earth(size_scale=4e3, distance_scale=1.3), # 地球放大 4000 倍,距离放大 1.3 倍 + Mars(size_scale=4e3, distance_scale=1.2), # 火星放大 4000 倍,距离放大 1.2 倍 + Asteroids(size_scale=1e2, parent=self.sun), # 小行星模拟(仅 ursina 模拟器支持) + Jupiter(size_scale=0.68e3, distance_scale=0.72), # 木星放大 680 倍,距离缩小到真实距离的 0.72 + Saturn(size_scale=0.68e3, distance_scale=0.52), # 土星放大 680 倍,距离缩小到真实距离的 0.52 + Uranus(size_scale=0.8e3, distance_scale=0.36), # 天王星放大 800 倍,距离缩小到真实距离的 0.36 + Neptune(size_scale=1e3, distance_scale=0.27), # 海王星放大 1000 倍,距离缩小到真实距离的 0.27 + Pluto(size_scale=10e3, distance_scale=0.23), # 冥王星放大 10000 倍,距离缩小到真实距离的 0.23(从太阳系的行星中排除) + ] + # endregion + init_pos_vels = self.get_init_pos_vels() + + for body in self.bodies: + pos_vels = init_pos_vels.get(type(body).__name__.lower(), None) + if pos_vels is None: + continue + body.init_position = pos_vels['pos'] + body.init_velocity = pos_vels['vel'] + + def build_two_way_foil(self): + self.two_way_foil = QuadObj(texture='wave.jpg', size_scale=4e7, + init_velocity=[0, 0, 100], + init_position=[0, 0, -10 * AU]) \ + .set_light_disable(True).set_ignore_gravity(True) - def create_two_dim(body): - body_2 = CircleObj(texture=body.texture, - size_scale=body.diameter * body.size_scale, - distance_scale=body.distance_scale, - init_position=body.position) \ + self.two_way_foil_circle = CircleObj(texture=self.two_way_foil.texture, + size_scale=self.two_way_foil.size_scale * 2, + ) \ .set_light_disable(True).set_ignore_gravity(True) - body.two_dim = body_2 - body_2.three_dim = body - return body_2 + def create_two_dim(self, body): + body_2dim = CircleObj(texture=body.texture, + size_scale=body.diameter * body.size_scale, + distance_scale=body.distance_scale, + init_position=body.position) \ + .set_light_disable(True).set_ignore_gravity(True) + body.two_dim = body_2dim + body_2dim.three_dim = body + return body_2dim - for body in bodies: - two_dim_body = create_two_dim(body) - three_dim_bodies.append(body) - two_dim_bodies.append(two_dim_body) + def build_two_dim_bodies(self): + for body in self.bodies: + two_dim_body = self.create_two_dim(body) + self.three_dim_bodies.append(body) + self.two_dim_bodies.append(two_dim_body) - bodies.append(two_way_foil) - bodies.append(two_way_foil_circle) + self.bodies.append(self.two_way_foil) + self.bodies.append(self.two_way_foil_circle) - for body in two_dim_bodies: - bodies.append(body) + for body in self.two_dim_bodies: + self.bodies.append(body) + def build(self): + self.build_solar_system() + self.build_two_way_foil() + self.build_two_dim_bodies() - def on_ready(): + def on_ready(self): """ 事件绑定后,模拟器运行前会触发 @return: @@ -169,39 +147,35 @@ if __name__ == '__main__': # camera.clip_plane_near = 0.1 camera.clip_plane_far = 1000000 create_sphere_sky(scale=200000) - for body in two_dim_bodies: + application.time_scale = 3 + for body in self.two_dim_bodies: body.planet.enabled = False model = body.planet.model if body.three_dim.has_rings: rings = create_rings(body.planet) rings.scale *= 2e10 - two_way_foil_circle.planet.rotation_x = 90 - two_way_foil_circle.planet.enabled = False - for b in two_dim_bodies: + self.two_way_foil_circle.planet.rotation_x = 90 + self.two_way_foil_circle.planet.enabled = False + for b in self.two_dim_bodies: b.planet.rotation_x = 90 - - current_stage = None - - - def stage_01(): + def stage_01(self): """ 二向箔飞向太阳 @return: """ - global current_stage - if two_bodies_colliding(two_way_foil, sun): - sun.planet.enabled = False - sun.two_dim.planet.enabled = True + if two_bodies_colliding(self.two_way_foil, self.sun): + self.sun.planet.enabled = False + self.sun.two_dim.planet.enabled = True + self.sun.two_dim.planet.x += 100000 # two_way_foil.explode(sun) - two_way_foil.planet.enabled = False - two_way_foil_circle.planet.alpha = 0.5 - two_way_foil_circle.planet.enabled = True - current_stage = stage_02 - + self.two_way_foil.planet.enabled = False + self.two_way_foil_circle.planet.alpha = 0.7 + self.two_way_foil_circle.planet.enabled = True + self.current_stage = self.stage_02 - def blink(body): + def blink(self, body): if not hasattr(body, "blink_d"): body.blink_d = 1 body.blink_v = 1 @@ -217,78 +191,51 @@ if __name__ == '__main__': if body.blink_v >= 1: body.blink_d = 1 - - def stage_02(): + def stage_02(self): """ @return: """ - global current_stage - sun.two_dim.planet.init_scale += 0.01 - two_way_foil_circle.planet.init_scale += 0.8 - blink(sun.two_dim) - for b in three_dim_bodies: - if two_bodies_colliding(two_way_foil_circle, b): + self.sun.two_dim.planet.init_scale += 0.05 + self.two_way_foil_circle.planet.init_scale += 0.8 + self.blink(self.sun.two_dim) + for b in self.three_dim_bodies: + if two_bodies_colliding(self.two_way_foil_circle, b): b.planet.enabled = False b.two_dim.planet.enabled = True if b.two_dim.planet.enabled: - b.two_dim.planet.init_scale += 0.01 - blink(b.two_dim) - - - current_stage = stage_01 - - - def on_timer_changed(time_data): - two_way_foil.planet.rotation_x += 1 - two_way_foil.planet.rotation_y += 2 - current_stage() - # if sun.two_dim.planet.enabled: - # sun.two_dim.planet.init_scale += 1.1 - # for b in three_dim_bodies: - # if two_bodies_colliding(sun.two_dim, b): - # b.planet.enabled = False - # b.two_dim.planet.enabled = True - # if b.two_dim.planet.enabled: - # b.two_dim.planet.init_scale += 1.1 - # else: - # if two_bodies_colliding(two_way_foil, sun): - # sun.planet.enabled = False - # sun.two_dim.planet.enabled = True - - # for b in three_dim_bodies: - # b.planet.enabled = False - init_pos_vels_info = "" - for b in two_dim_bodies: - # b.planet.rotation_x = 90 + b.two_dim.planet.init_scale += 0.05 + self.blink(b.two_dim) + self.two_way_foil_circle.planet.rotation_z += 0.2 + + def on_timer_changed(self, time_data): + self.two_way_foil.planet.rotation_x += 1 + self.two_way_foil.planet.rotation_y += 10 + self.current_stage() + for b in self.two_dim_bodies: b.init_position = b.three_dim.position - pos, vel = b.three_dim.position, b.three_dim.velocity - t_name = type(b.three_dim).__name__.lower() - init_pos_vels_info += f" init_pos_vels['{t_name}'] = {{}}" - init_pos_vels_info += f" init_pos_vels['{t_name}']['pos'] = [%.4f,%.4f,%.4f]\n" % ( - pos[0], pos[1], pos[2]) - init_pos_vels_info += f" init_pos_vels['{t_name}']['vel'] = [%.4f,%.4f,%.4f]\n" % ( - vel[0], vel[1], vel[2]) - # init_pos_vels['sun'] = {} - # init_pos_vels['sun']['pos'] = [120062.8111, -462734.9565, -198328.7512] - # init_pos_vels['sun']['vel'] = [0.0093, 0.0037, 0.0014] - - # print(b.planet.position, b.three_dim.planet.position) - print("----------------------------------------------") - print(init_pos_vels_info) - - pass +if __name__ == '__main__': + """ + 三体二向箔场景模拟 + """ + sim = TwoWayFoilSim() + sim.build() # 订阅事件后,上面2个函数功能才会起作用 # 运行中,每时每刻都会触发 on_timer_changed - UrsinaEvent.on_timer_changed_subscription(on_timer_changed) + UrsinaEvent.on_timer_changed_subscription(sim.on_timer_changed) # 运行前会触发 on_ready - UrsinaEvent.on_ready_subscription(on_ready) + UrsinaEvent.on_ready_subscription(sim.on_ready) # 使用 ursina 查看的运行效果 # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 # position = 左-右+、上+下-、前+后- - ursina_run(bodies, SECONDS_PER_MONTH / 2, position=(0, 2 * AU, -11 * AU), + ursina_run(sim.bodies, + SECONDS_PER_MONTH / 2, + # position=(0, 2 * AU, -11 * AU), + position=(0, 1 * AU, -11 * AU), cosmic_bg='', + show_camera_info=False, + show_control_info=False, timer_enabled=True, show_grid=False)