# -*- coding:utf-8 -*- # title :虫洞效果模拟 # description :虫洞效果模拟 # author :Python超人 # date :2023-11-03 # link :https://gitcode.net/pythoncr/ # python_version :3.9 # ============================================================================== from bodies import Sun, Earth from common.consts import SECONDS_PER_DAY, SECONDS_PER_WEEK, SECONDS_PER_MONTH, SECONDS_PER_YEAR, AU from objs import Obj, SpaceShip, StarWarsSpeeder, ScifiGunship, SciFiBomber, CoreValagaClas from sim_scenes.func import mayavi_run, mpl_run, ursina_run, camera_look_at, two_bodies_colliding from ursina import camera, application, lerp from bodies import Body from simulators.ursina.ursina_event import UrsinaEvent ours_cosmic_bg = "bg_pan.jpg" worms_cosmic_bg = "cosmic3.jpg" class UniverseBody(Body): def __init__(self, name="虫洞", mass=1.9891e35, init_position=[0, 0, 0], init_velocity=[0, 0, 0], color=(0, 0, 0), texture=None, density=1.408e20, size_scale=1.0, distance_scale=1.0, rotation_speed=0, ignore_mass=False, trail_color=None, show_name=False): params = { "name": name, "mass": mass, "init_position": init_position, "init_velocity": init_velocity, "density": density, "color": color, "texture": texture, "size_scale": size_scale * 10000, "distance_scale": distance_scale, "rotation_speed": rotation_speed, "ignore_mass": ignore_mass, "trail_color": trail_color, "show_name": show_name } super().__init__(**params) class WormHole(UniverseBody): def __init__(self, name="虫洞", mass=1.9891e35, texture=worms_cosmic_bg, size_scale=1.0, init_position=[0, 0, 0], init_velocity=[0, 0, 0]): params = { "name": name, "mass": mass, "init_position": init_position, "init_velocity": init_velocity, "density": 1.408e20, # "color": color, "texture": texture, "size_scale": size_scale, # "distance_scale": distance_scale, # "rotation_speed": rotation_speed, # "ignore_mass": ignore_mass, # "trail_color": trail_color, # "show_name": show_name } super().__init__(**params) class OursUniverse(UniverseBody): def __init__(self, name="我们的宇宙", texture=ours_cosmic_bg, size_scale=1.0, init_position=[0, 0, 0], init_velocity=[0, 0, 0]): params = { "name": name, "mass": 1.9891e35, "init_position": init_position, "init_velocity": init_velocity, "density": 1.408e20, # "color": color, "texture": texture, "size_scale": size_scale, # "distance_scale": distance_scale, # "ignore_mass": ignore_mass, # "trail_color": trail_color, # "show_name": show_name } super().__init__(**params) if __name__ == '__main__': """ """ # 代码案例如下: SIZE_SCALE = 1e1 # 生成的太阳放大 50 倍 RUN_DIAMETER = 1.392e6 velocity_rate = 22 camera_target = CoreValagaClas(name="摄像机目标", mass=1e30, color=(111, 140, 255), init_position=[0, 0, -AU], init_velocity=[0, 0, 0], size_scale=SIZE_SCALE * 1e1) # .set_ignore_gravity(True) ours_universe = OursUniverse( # size_scale=SIZE_SCALE * 1e3, size_scale=SIZE_SCALE , init_position=[0, 0, -AU], init_velocity=[0, 0, 0], ).set_ignore_gravity(True) worm_hole = WormHole( # init_position=[RUN_DIAMETER, RUN_DIAMETER, 0], init_position=[0, 0, AU], init_velocity=[0, 0, 0], size_scale=SIZE_SCALE) # .set_ignore_gravity(True) bodies = [ # camera_target, ours_universe, worm_hole ] camera_position = [0, 0, 0] def on_ready(): """ 事件绑定后,模拟器运行前会触发 @return: """ # 创建天空 camera.clip_plane_near = 0.001 camera.clip_plane_far = 10000000000000 # create_sphere_sky(scale=200000) application.time_scale = 0.001 # camera.scale = 1000 # camera.parent = camera_target.planet # camera.rotation_x = 90 camera_look_at(worm_hole) camera.collider="sphere" worm_hole.planet.collider="sphere" ours_universe.planet.init_scale = SIZE_SCALE*1000 # camera_position = camera.position def on_timer_changed(time_data): global camera_position # pass # camera_look_at(camera_target) # camera.rotation_x -= 2 # camera_target.planet.look_at(worm_hole.planet) if camera.intersects(worm_hole.planet).hit: if worm_hole.planet.init_scale < SIZE_SCALE*1000: worm_hole.planet.init_scale *= 1.1 if ours_universe.planet.init_scale > SIZE_SCALE: ours_universe.planet.init_scale /= 1.1 camera.rotation_y += 0.1 # camera_look_at(ours_universe) else: # if two_bodies_colliding(camera_target, worm_hole): # camera_target.stop_and_ignore_gravity() # print(1,camera_target.planet.position) # camera_target.planet.position = lerp(camera_target.planet.position, worm_hole.planet.position, 1e-2) # print(2,camera_target.planet.position) camera.position = lerp(camera.position, worm_hole.planet.position, 1e-2) # camera_position = [camera_position[0], camera_position[1], camera_position[2] - 0.01] # camera.position = camera_position # 订阅事件后,上面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_DAY / 24, # position=(0, AU / 1200, -1.003 * AU), cosmic_bg='', # gravity_works=False, timer_enabled=True, show_grid=False, show_trail=False)