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

Python超人-宇宙模拟器

上级 70e991aa
# -*- coding:utf-8 -*-
# title :遨游太阳系
# description :遨游太阳系
# author :Python超人
# date :2024-03-04
# link :https://gitcode.net/pythoncr/
# python_version :3.9
# ==============================================================================
from ursina import camera, application, lerp, Vec3
from bodies import Sun, Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto
from common.celestial_data_service import init_bodies_reality_pos_vels, conv_to_astropy_time, \
set_solar_system_celestial_position, init_bodies_pos_vels, get_init_pos_vels_2
from common.consts import SECONDS_PER_YEAR,SECONDS_PER_MINUTE,SECONDS_PER_HOUR, AU
from common.func import calculate_distance
from bodies import Earth
from objs import QuadObj, CircleObj, Obj, CoreValagaClas
from sim_scenes.func import create_text_panel, camera_look_at, get_run_speed_factor, \
camera_move_update, camera_move_to_target_update, camera_move_control, two_bodies_colliding
from sim_scenes.func import ursina_run, create_sphere_sky
from sim_scenes.solar_system.halley_comet_lib import HalleyCometSimBase, HalleyCometParams, \
create_halley_comet, create_orbit_line
from sim_scenes.universe_sim_scenes import UniverseSimScenes
from simulators.func import ext_fun_for_method
from simulators.ursina.entities.body_timer import TimeData
from simulators.ursina.entities.entity_utils import get_value_direction_vectors
from simulators.ursina.ui.control_ui import ControlUI
from simulators.ursina.ursina_config import UrsinaConfig
from simulators.ursina.ursina_event import UrsinaEvent
from simulators.ursina.ursina_mesh import create_label
import time
class SolarSystemExplorer(UniverseSimScenes):
"""
遨游太阳系
"""
def build_solar_system(self):
# region 构建太阳系
show_trail = False
self.SIZE_FACTOR = 0.01
self.init_pos = [2 * AU, 2 * AU, -10 * AU]
self.sun = Sun(size_scale=20e2*self.SIZE_FACTOR, show_trail=show_trail,
# color=(255, 250, 245),
# texture="",
texture="sun_light.jpg"
)
self.sun.glows = (24, 1.008, 0.04)
self.sun.set_resolution(200)
self.mercury = Mercury(size_scale=2e3*self.SIZE_FACTOR, distance_scale=1.6, show_trail=show_trail)
self.venus = Venus(size_scale=2e3*self.SIZE_FACTOR, distance_scale=1.5, show_trail=show_trail)
self.earth = Earth(size_scale=2e3*self.SIZE_FACTOR, distance_scale=1.5, rotate_angle=0, show_trail=show_trail)
self.mars = Mars(size_scale=2e3*self.SIZE_FACTOR, distance_scale=1.4, show_trail=show_trail)
self.jupiter = Jupiter(size_scale=0.3e3*self.SIZE_FACTOR, distance_scale=0.7, show_trail=show_trail)
self.saturn = Saturn(size_scale=0.3e3*self.SIZE_FACTOR, distance_scale=0.52, show_trail=show_trail)
self.uranus = Uranus(size_scale=0.8e3*self.SIZE_FACTOR, distance_scale=0.34, show_trail=show_trail)
self.neptune = Neptune(size_scale=0.8e3*self.SIZE_FACTOR, distance_scale=0.25, show_trail=show_trail)
self.pluto = Pluto(size_scale=1e4*self.SIZE_FACTOR, distance_scale=0.23, show_trail=show_trail)
D = AU / 10
self.camera_target = CoreValagaClas(name="摄像机镜头", mass=1e30, color=(111, 140, 255),
# init_position=[0, 0, 0],
init_position=self.init_pos,
init_velocity=[0, 0, 0],
size_scale=1e3*self.SIZE_FACTOR).set_ignore_gravity(True)
self.bodies = [
self.sun, # 太阳
self.mercury, # 水星
self.venus, # 金星
self.earth, # 地球
self.mars, # 火星
self.jupiter, # 木星
self.saturn, # 土星
self.uranus, # 天王星
self.neptune, # 海王星
self.pluto, # 冥王星
self.camera_target
]
init_bodies_pos_vels(self.bodies, init_pos_vels_fun=self.get_init_pos_vels)
def get_init_pos_vels(self):
init_pos_vels = {}
init_pos_vels['sun'] = {}
init_pos_vels['sun']['pos'] = [-23.205570220947266, 0.0, 494.46502685546875]
init_pos_vels['sun']['vel'] = [-3.617262336774729e-05, 0.0, 0.000522326270584017]
init_pos_vels['mercury'] = {}
init_pos_vels['mercury']['pos'] = [-56858320.0, 0.0, -237695.5]
init_pos_vels['mercury']['vel'] = [0.5191680788993835, 0.0, -48.36161804199219]
init_pos_vels['venus'] = {}
init_pos_vels['venus']['pos'] = [-61601512.0, 0.0, 88374768.0]
init_pos_vels['venus']['vel'] = [-28.69715118408203, 0.0, -20.112533569335938]
init_pos_vels['earth'] = {}
init_pos_vels['earth']['pos'] = [-54543052.0, 0.0, 139275888.0]
init_pos_vels['earth']['vel'] = [-27.743507385253906, 0.0, -10.863121032714844]
init_pos_vels['mars'] = {}
init_pos_vels['mars']['pos'] = [-44924356.0, 0.0, 222884576.0]
init_pos_vels['mars']['vel'] = [-23.654102325439453, 0.0, -4.7799787521362305]
init_pos_vels['asteroids'] = {}
init_pos_vels['asteroids']['pos'] = [0.0, 0.0, 0.0]
init_pos_vels['asteroids']['vel'] = [0.0, 0.0, 0.0]
init_pos_vels['jupiter'] = {}
init_pos_vels['jupiter']['pos'] = [-24472074.0, 0.0, 776025472.0]
init_pos_vels['jupiter']['vel'] = [-13.053510665893555, 0.0, -0.4124884009361267]
init_pos_vels['saturn'] = {}
init_pos_vels['saturn']['pos'] = [-18066134.0, 0.0, 1421063552.0]
init_pos_vels['saturn']['vel'] = [-9.6392240524292, 0.0, -0.12374488264322281]
init_pos_vels['uranus'] = {}
init_pos_vels['uranus']['pos'] = [-12762774.0, 0.0, 2872276736.0]
init_pos_vels['uranus']['vel'] = [-6.809953689575195, 0.0, -0.030240831896662712]
init_pos_vels['neptune'] = {}
init_pos_vels['neptune']['pos'] = [-10176475.0, 0.0, 4592654848.0]
init_pos_vels['neptune']['vel'] = [-5.429999828338623, 0.0, -0.011822682805359364]
init_pos_vels['pluto'] = {}
init_pos_vels['pluto']['pos'] = [-8808451.0, 0.0, 5916595712.0]
init_pos_vels['pluto']['vel'] = [-4.699999809265137, 0.0, -0.007128323893994093]
return init_pos_vels
def build(self):
"""
构建太阳系系统以及哈雷彗星
@return:
"""
self.build_solar_system()
def init_settings(self):
"""
初始化设置
@return:
"""
from ursina import color
# 创建天空
create_sphere_sky(texture="bg_pan2.jpg", scale=50000, rotation_x=200, rotation_y=None, rotation_z=45)
# UrsinaConfig.trail_type = "curve_line"
# UrsinaConfig.trail_length = 300
UrsinaConfig.trail_type = "line"
# UrsinaConfig.trail_length = 152 # 尾巴数量刚刚好
UrsinaConfig.trail_length = 130
UrsinaConfig.trail_thickness_factor = 3
# UrsinaConfig.trail_length = 180
UrsinaConfig.trail_factor = 3
# camera.clip_plane_near = 0.1
camera.clip_plane_far = 51000
application.time_scale = 0.001
# camera.fov = 60
# self.current_stage = self.stage_01
def s_f(self, value=1):
if value == 0:
return 0
return get_run_speed_factor() * value
def camera_move(self, time_data):
"""
摄像机移动控制
@param dt:
@return:
"""
# 摄像机移动控制数据
camera_move_infos = [
# 条件:年份
# 移动的信息:
# 按坐标系方向移动 x:右+左-, y:升+降-, z:前+(接近太阳)后-(远离太阳)
# 以摄像机视角移动 f:前 b:后 l:左 r:右 u:上 d:下
(0, {"f": 5.758}),
# (1983, {"to": {"ct_id": 1, "t": 10}}),
(11, {"f": 1.8}),
(14, {"f": 2}),
(18, {"f": 2}),
(25, {"f": 1}),
(28, {"f": 0.2}),
# (30, {"f": 0.5}),
# (40, {"f": 0.6}),
(33, {"b": 2}),
(50, {"f": 0.2}),
(65, {"f": 2}),
(69, {"f": 3}),
(70, {"f": 4}),
(75, {"f": 5}),
(90, {"f": 3}),
(200, {}),
# (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}),
]
if time_data.total_days > 120:
# self.two_way_foil_circle.planet.enabled = False
self.two_way_foil.scale_factor = 0.5
if 100 > time_data.total_days > 28:
self.two_way_foil.scale_factor -= 1.5e-3
def cond_cb(ps):
return ps["next_cond"] > time_data.total_days >= ps["cond"]
camera_move_control(camera_move_infos,
cond_cb=cond_cb,
value_conv=self.s_f, smooth=1)
def get_target(self):
for body in self.bodies:
if hasattr(body, "is_arrived"):
continue
return body
return None
def last_target(self):
return self.sun
def on_ready(self):
"""
事件绑定后,模拟器运行前会触发
@return:
"""
# 初始化设置
self.init_settings()
# self.set_window_size((int(1920 * r), int(1080 * r)), False)
# 最大分辨率的高度-1,保证不全屏
# self.set_window_size((1920, 1079), False)
application.time_scale = 0.00001
camera.speed = 4e2
self.camera_target.planet.update = lambda: None
# 显示网格以及坐标线
# self.show_grid_axises()
def go_target(self):
from ursina import distance
target = self.get_target()
target_scale = target.planet.scale_x
target_pos = target.planet.position + Vec3(0, target_scale * (3 / 5), 0)
self.camera_target.planet.look_at(target_pos)
dd = distance(self.camera_target.planet.position, target_pos)
if not hasattr(target, "distance"):
target.distance = dd
self.camera_target.planet.position = lerp(self.camera_target.planet.position, target_pos,
camera.speed * time.dt * target.distance)
camera_target_pos =self.camera_target.planet.position
dd2 = distance(camera.position, camera_target_pos)
camera.position = lerp(camera.position, camera_target_pos,
camera.speed * 0.99 * time.dt * target.distance)
if dd < target_scale * 3 and dd2 < target_scale*3:
if target is not None:
target.is_arrived = True
camera_look_at(self.camera_target, rotation_z=0)
# print(camera.position)
print(target.name, target_scale, dd, self.camera_target.planet.position)
# print(dd)
def on_timer_changed(self, time_data):
"""
@param time_data:
@return:
"""
self.go_target()
# self.camera_move(time_data)
# self.current_stage()
if __name__ == '__main__':
"""
"""
# params = TwoWayFoilSim()
sim = SolarSystemExplorer()
# window_size = (1920, 1079)
# UniverseSimScenes.set_window_size(window_size, False)
sim.build()
# 订阅事件后,上面2个函数功能才会起作用
# 运行中,每时每刻都会触发 on_timer_changed
UrsinaEvent.on_timer_changed_subscription(sim.on_timer_changed)
# 运行前会触发 on_ready
UrsinaEvent.on_ready_subscription(sim.on_ready)
# 使用 ursina 查看的运行效果
# 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹
# position = 左-右+、上+下-、前+后-
ursina_run(sim.bodies,
# SECONDS_PER_YEAR / 48 * get_run_speed_factor(),
SECONDS_PER_MINUTE,
# position=(0, 2 * AU, -11 * AU),
# position=(0, 0.5 * AU, -5 * AU),
# position=(2 * AU, -5 * AU, -20 * AU),
position=sim.init_pos,
cosmic_bg='',
# show_trail=True,
# bg_music='sounds/no_glory.mp3',
show_camera_info=False,
# video_recoder=True,
show_control_info=False,
# save_cube_map=True,
timer_enabled=True,
# show_timer=True,
show_grid=False
)
# -*- coding:utf-8 -*-
# title :太阳系场景位置生成器
# description :太阳系场景位置生成器
# author :Python超人
# date :2023-02-11
# link :https://gitcode.net/pythoncr/
# python_version :3.8
# ==============================================================================
from bodies import Sun, Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto, Moon, Asteroids
from common.consts import SECONDS_PER_WEEK, SECONDS_PER_DAY, SECONDS_PER_YEAR, AU, SECONDS_PER_MONTH
from sim_scenes.func import mayavi_run, ursina_run
from simulators.ursina.ursina_event import UrsinaEvent
if __name__ == '__main__':
# 八大行星:木星(♃)、土星(♄)、天王星(♅)、海王星(♆)、地球(⊕)、金星(♀)、火星(♂)、水星(☿)
# 排列顺序
# 1、体积:(以地球为1)木星 :土星 :天王星 :海王星 :地球 :金星 :火星 :水星 = 1330:745:65:60:1:0.86:0.15:0.056
# 2、质量:(以地球为1)木星 :土星 :天王星 :海王星 :地球 :金星 :火星 :水星 = 318:95:14.53:17.15:1:0.8:0.11:0.0553
# 3、离太阳从近到远的顺序:水星、金星、地球、火星、木星、土星、天王星、海王星
# =====================================================================
# 以下展示的效果为太阳系真实的距离
# 由于宇宙空间尺度非常大,如果按照实际的天体大小,则无法看到天体,因此需要对天体的尺寸进行放大
sun = Sun(name="太阳", size_scale=0.8e2) # 太阳放大 80 倍,距离保持不变
bodies = [
sun,
Mercury(name="水星", size_scale=4e3), # 水星放大 4000 倍,距离保持不变
Venus(name="金星", size_scale=4e3), # 金星放大 4000 倍,距离保持不变
Earth(name="地球", size_scale=4e3), # 地球放大 4000 倍,距离保持不变
Mars(name="火星", size_scale=4e3), # 火星放大 4000 倍,距离保持不变
Asteroids(name="小行星群", size_scale=1e2,
parent=sun), # 小行星群模拟(仅 ursina 模拟器支持)
Jupiter(name="木星", size_scale=0.8e3), # 木星放大 800 倍,距离保持不变
Saturn(name="土星", size_scale=0.8e3), # 土星放大 800 倍,距离保持不变
Uranus(name="天王星", size_scale=0.8e3), # 天王星放大 800 倍,距离保持不变
Neptune(name="海王星", size_scale=1e3), # 海王星放大 1000 倍,距离保持不变
Pluto(name="冥王星", size_scale=10e3), # 冥王星放大 10000 倍,距离保持不变(从太阳系的行星中排除)
]
def on_timer_changed(time_data):
init_pos_vels = """
----------------------------------------------
def get_init_pos_vels():
init_pos_vels = {}"""
for body in bodies:
body_name = body.__class__.__name__.lower()
pos = body.position
vel = body.velocity
init_pos_vels += f"""
init_pos_vels['{body_name}'] = {{}}
init_pos_vels['{body_name}']['pos'] = [{pos[0]}, {pos[1]}, {pos[2]}]
init_pos_vels['{body_name}']['vel'] = [{vel[0]}, {vel[1]}, {vel[2]}]"""
init_pos_vels += """
return init_pos_vels"""
print(init_pos_vels)
def on_ready():
pass
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/10, position=(0, 2 * AU, -11 * AU),
timer_enabled=True)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册