提交 d74226e8 编写于 作者: 三月三net's avatar 三月三net

Python超人-宇宙模拟器

上级 6b799320
objs/textures/caustic.jpg

77.2 KB | W: | H:

objs/textures/caustic.jpg

479.5 KB | W: | H:

objs/textures/caustic.jpg
objs/textures/caustic.jpg
objs/textures/caustic.jpg
objs/textures/caustic.jpg
  • 2-up
  • Swipe
  • Onion skin
# -*- 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)
...@@ -16,7 +16,7 @@ from simulators.ursina.entities.body_timer import TimeData ...@@ -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.entities.entity_utils import create_directional_light, create_rings
from simulators.ursina.ursina_config import UrsinaConfig from simulators.ursina.ursina_config import UrsinaConfig
from simulators.ursina.ursina_event import UrsinaEvent 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 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 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 ...@@ -24,143 +24,121 @@ from sim_scenes.func import mayavi_run, ursina_run, create_sphere_sky
from simulators.ursina.ursina_event import UrsinaEvent from simulators.ursina.ursina_event import UrsinaEvent
def get_init_pos_vels(): class TwoWayFoilSim:
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 构建太阳系 def __init__(self):
sun = Sun(size_scale=0.8e2)
bodies = [ self.three_dim_bodies = []
sun, # 太阳放大 80 倍 self.two_dim_bodies = []
Mercury(size_scale=4e3, distance_scale=1.3), # 水星放大 4000 倍,距离放大 1.3 倍 self.current_stage = self.stage_01
Venus(size_scale=4e3, distance_scale=1.3), # 金星放大 4000 倍,距离放大 1.3 倍
Earth(size_scale=4e3, distance_scale=1.3), # 地球放大 4000 倍,距离放大 1.3 倍 def get_init_pos_vels(self):
Mars(size_scale=4e3, distance_scale=1.2), # 火星放大 4000 倍,距离放大 1.2 倍 init_pos_vels = {}
Asteroids(size_scale=1e2, parent=sun), # 小行星模拟(仅 ursina 模拟器支持) init_pos_vels['sun'] = {}
Jupiter(size_scale=0.68e3, distance_scale=0.72), # 木星放大 680 倍,距离缩小到真实距离的 0.72 init_pos_vels['sun']['pos'] = [-4638653.0000, 0.0000, 1314332.6250]
Saturn(size_scale=0.68e3, distance_scale=0.52), # 土星放大 680 倍,距离缩小到真实距离的 0.52 init_pos_vels['sun']['vel'] = [-0.0165, 0.0000, -0.0097]
Uranus(size_scale=0.8e3, distance_scale=0.36), # 天王星放大 800 倍,距离缩小到真实距离的 0.36 init_pos_vels['mercury'] = {}
Neptune(size_scale=1e3, distance_scale=0.27), # 海王星放大 1000 倍,距离缩小到真实距离的 0.27 init_pos_vels['mercury']['pos'] = [-54412616.0000, 0.0000, 31280100.0000]
Pluto(size_scale=10e3, distance_scale=0.23), # 冥王星放大 10000 倍,距离缩小到真实距离的 0.23(从太阳系的行星中排除) init_pos_vels['mercury']['vel'] = [-25.2667, 0.0000, -40.0561]
] init_pos_vels['venus'] = {}
# endregion 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 = get_init_pos_vels() init_pos_vels['earth'] = {}
init_pos_vels['earth']['pos'] = [140427392.0000, 0.0000, 45724572.0000]
for body in bodies: init_pos_vels['earth']['vel'] = [-8.1280, 0.0000, 28.2277]
pos_vels = init_pos_vels.get(type(body).__name__.lower(), None) init_pos_vels['mars'] = {}
if pos_vels is None: init_pos_vels['mars']['pos'] = [218751648.0000, 0.0000, -45263688.0000]
continue init_pos_vels['mars']['vel'] = [5.2205, 0.0000, 23.4601]
body.init_position = pos_vels['pos'] init_pos_vels['asteroids'] = {}
body.init_velocity = pos_vels['vel'] init_pos_vels['asteroids']['pos'] = [0.0000, 0.0000, 0.0000]
init_pos_vels['asteroids']['vel'] = [0.0000, 0.0000, 0.0000]
two_way_foil = QuadObj(texture='caustic.jpg', size_scale=4e7, init_pos_vels['jupiter'] = {}
init_velocity=[0, 0, 100], init_pos_vels['jupiter']['pos'] = [769445760.0000, 0.0000, 2017638.5000]
init_position=[0, 0, -10 * AU]) \ init_pos_vels['jupiter']['vel'] = [0.0389, 0.0000, 13.0879]
.set_light_disable(True).set_ignore_gravity(True) init_pos_vels['saturn'] = {}
init_pos_vels['saturn']['pos'] = [-1330536704.0000, 0.0000, -454165280.0000]
two_way_foil_circle = CircleObj(texture=two_way_foil.texture, init_pos_vels['saturn']['vel'] = [3.2189, 0.0000, -9.1974]
size_scale=two_way_foil.size_scale * 2, init_pos_vels['uranus'] = {}
) \ init_pos_vels['uranus']['pos'] = [-1757163648.0000, 0.0000, 2272503808.0000]
.set_light_disable(True).set_ignore_gravity(True) init_pos_vels['uranus']['vel'] = [-5.3918, 0.0000, -4.1634]
init_pos_vels['neptune'] = {}
three_dim_bodies = [] init_pos_vels['neptune']['pos'] = [-1480893824.0000, 0.0000, 4351772160.0000]
two_dim_bodies = [] 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): self.two_way_foil_circle = CircleObj(texture=self.two_way_foil.texture,
body_2 = CircleObj(texture=body.texture, size_scale=self.two_way_foil.size_scale * 2,
size_scale=body.diameter * body.size_scale, ) \
distance_scale=body.distance_scale,
init_position=body.position) \
.set_light_disable(True).set_ignore_gravity(True) .set_light_disable(True).set_ignore_gravity(True)
body.two_dim = body_2 def create_two_dim(self, body):
body_2.three_dim = body body_2dim = CircleObj(texture=body.texture,
return body_2 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: def build_two_dim_bodies(self):
two_dim_body = create_two_dim(body) for body in self.bodies:
three_dim_bodies.append(body) two_dim_body = self.create_two_dim(body)
two_dim_bodies.append(two_dim_body) self.three_dim_bodies.append(body)
self.two_dim_bodies.append(two_dim_body)
bodies.append(two_way_foil) self.bodies.append(self.two_way_foil)
bodies.append(two_way_foil_circle) self.bodies.append(self.two_way_foil_circle)
for body in two_dim_bodies: for body in self.two_dim_bodies:
bodies.append(body) 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: @return:
...@@ -169,39 +147,35 @@ if __name__ == '__main__': ...@@ -169,39 +147,35 @@ if __name__ == '__main__':
# camera.clip_plane_near = 0.1 # camera.clip_plane_near = 0.1
camera.clip_plane_far = 1000000 camera.clip_plane_far = 1000000
create_sphere_sky(scale=200000) 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 body.planet.enabled = False
model = body.planet.model model = body.planet.model
if body.three_dim.has_rings: if body.three_dim.has_rings:
rings = create_rings(body.planet) rings = create_rings(body.planet)
rings.scale *= 2e10 rings.scale *= 2e10
two_way_foil_circle.planet.rotation_x = 90 self.two_way_foil_circle.planet.rotation_x = 90
two_way_foil_circle.planet.enabled = False self.two_way_foil_circle.planet.enabled = False
for b in two_dim_bodies: for b in self.two_dim_bodies:
b.planet.rotation_x = 90 b.planet.rotation_x = 90
def stage_01(self):
current_stage = None
def stage_01():
""" """
二向箔飞向太阳 二向箔飞向太阳
@return: @return:
""" """
global current_stage if two_bodies_colliding(self.two_way_foil, self.sun):
if two_bodies_colliding(two_way_foil, sun): self.sun.planet.enabled = False
sun.planet.enabled = False self.sun.two_dim.planet.enabled = True
sun.two_dim.planet.enabled = True self.sun.two_dim.planet.x += 100000
# two_way_foil.explode(sun) # two_way_foil.explode(sun)
two_way_foil.planet.enabled = False self.two_way_foil.planet.enabled = False
two_way_foil_circle.planet.alpha = 0.5 self.two_way_foil_circle.planet.alpha = 0.7
two_way_foil_circle.planet.enabled = True self.two_way_foil_circle.planet.enabled = True
current_stage = stage_02 self.current_stage = self.stage_02
def blink(body): def blink(self, body):
if not hasattr(body, "blink_d"): if not hasattr(body, "blink_d"):
body.blink_d = 1 body.blink_d = 1
body.blink_v = 1 body.blink_v = 1
...@@ -217,78 +191,51 @@ if __name__ == '__main__': ...@@ -217,78 +191,51 @@ if __name__ == '__main__':
if body.blink_v >= 1: if body.blink_v >= 1:
body.blink_d = 1 body.blink_d = 1
def stage_02(self):
def stage_02():
""" """
@return: @return:
""" """
global current_stage self.sun.two_dim.planet.init_scale += 0.05
sun.two_dim.planet.init_scale += 0.01 self.two_way_foil_circle.planet.init_scale += 0.8
two_way_foil_circle.planet.init_scale += 0.8 self.blink(self.sun.two_dim)
blink(sun.two_dim) for b in self.three_dim_bodies:
for b in three_dim_bodies: if two_bodies_colliding(self.two_way_foil_circle, b):
if two_bodies_colliding(two_way_foil_circle, b):
b.planet.enabled = False b.planet.enabled = False
b.two_dim.planet.enabled = True b.two_dim.planet.enabled = True
if b.two_dim.planet.enabled: if b.two_dim.planet.enabled:
b.two_dim.planet.init_scale += 0.01 b.two_dim.planet.init_scale += 0.05
blink(b.two_dim) self.blink(b.two_dim)
self.two_way_foil_circle.planet.rotation_z += 0.2
current_stage = stage_01 def on_timer_changed(self, time_data):
self.two_way_foil.planet.rotation_x += 1
self.two_way_foil.planet.rotation_y += 10
def on_timer_changed(time_data): self.current_stage()
two_way_foil.planet.rotation_x += 1 for b in self.two_dim_bodies:
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.init_position = b.three_dim.position 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个函数功能才会起作用 # 订阅事件后,上面2个函数功能才会起作用
# 运行中,每时每刻都会触发 on_timer_changed # 运行中,每时每刻都会触发 on_timer_changed
UrsinaEvent.on_timer_changed_subscription(on_timer_changed) UrsinaEvent.on_timer_changed_subscription(sim.on_timer_changed)
# 运行前会触发 on_ready # 运行前会触发 on_ready
UrsinaEvent.on_ready_subscription(on_ready) UrsinaEvent.on_ready_subscription(sim.on_ready)
# 使用 ursina 查看的运行效果 # 使用 ursina 查看的运行效果
# 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹
# position = 左-右+、上+下-、前+后- # 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='', cosmic_bg='',
show_camera_info=False,
show_control_info=False,
timer_enabled=True, timer_enabled=True,
show_grid=False) show_grid=False)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册