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

太阳系三体模拟器

上级 5d2f1f56
......@@ -6,8 +6,8 @@
# link :https://gitcode.net/pythoncr/
# python_version :3.8
# ==============================================================================
from bodies import Sun, Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto, Moon
from common.consts import SECONDS_PER_WEEK, SECONDS_PER_DAY, SECONDS_PER_YEAR
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
from scenes.func import mayavi_run, ursina_run
if __name__ == '__main__':
......@@ -19,21 +19,24 @@ if __name__ == '__main__':
# =====================================================================
# 以下展示的效果为太阳系真实的距离
# 由于宇宙空间尺度非常大,如果按照实际的天体大小,则无法看到天体,因此需要对天体的尺寸进行放大
sun = Sun(name="太阳", size_scale=0.8e2) # 太阳放大 80 倍,距离保持不变
bodies = [
Sun(size_scale=0.8e2), # 太阳放大 80 倍,距离保持不变
Mercury(size_scale=4e3), # 水星放大 4000 倍,距离保持不变
Venus(size_scale=4e3), # 金星放大 4000 倍,距离保持不变
Earth(size_scale=4e3), # 地球放大 4000 倍,距离保持不变
Mars(size_scale=4e3), # 火星放大 4000 倍,距离保持不变
Jupiter(size_scale=0.8e3), # 木星放大 800 倍,距离保持不变
Saturn(size_scale=0.8e3), # 土星放大 800 倍,距离保持不变
Uranus(size_scale=0.8e3), # 天王星放大 800 倍,距离保持不变
Neptune(size_scale=1e3), # 海王星放大 1000 倍,距离保持不变
Pluto(size_scale=10e3), # 冥王星放大 10000 倍,距离保持不变(从太阳系的行星中排除)
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=3.2e2,
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 倍,距离保持不变(从太阳系的行星中排除)
]
# 使用 mayavi 查看的运行效果
# mayavi_run(bodies, SECONDS_PER_WEEK, view_azimuth=-45)
# 使用 ursina 查看的运行效果
ursina_run(bodies, SECONDS_PER_YEAR, position=(0, 0, 0))
\ No newline at end of file
ursina_run(bodies, SECONDS_PER_YEAR, position=(0, 5 * AU, -10 * AU)) # position=左-右+、上+下-、前+后-
......@@ -149,15 +149,57 @@ class UrsinaUI:
else:
UrsinaConfig.show_trail = False
def move_camera_to_entity(self, camera_pos: Vec3, entity_pos: Vec3, _distance: float) -> Vec3:
# 计算摄像机到实体的向量
direction = entity_pos - camera_pos
# 计算当前距离
current_distance = direction.length()
# 如果当前距离已经小于等于要求的距离,则直接返回实体坐标
if current_distance <= _distance:
return camera_pos
# 计算需要移动的距离
_distance = current_distance - _distance
# 根据需要移动的距离计算移动向量
move_vector = direction.normalized() * _distance
# 返回摄像机移动后的坐标
return camera_pos + move_vector
def move_camera_to_entity(self,entity,d):
import math
# print("before",camera.position, entity.position)
camera.position = entity.position #- Vec3(0, 0, d) # 设置摄像机位置
camera.world_position = entity.position
# camera.rotation = (0, 0, 0) # 重置摄像机旋转角度
# print("after",camera.position,entity.position)
# # 获取相机和实体之间的向量
# target_vector = entity.position - camera.position
# target_vector.y = 0 # 假设实体在 x-z 平面上,将 y 坐标设为 0
#
# # 计算旋转角度
# angle = math.degrees(math.atan2(target_vector.z, target_vector.x))
# camera.rotation_y = angle # 旋转相机
# camera.look_at(entity.position) # 对准指定实体
def bodies_button_list_click(self, item):
if item is not None:
# TODO: 先找到位置,确定摄像机的位置
# print("select->", item)
# UrsinaConfig.SCALE_FACTOR
x = item.planet.scale_x * 10
camera.position = item.planet.position + Vec3(-x, 0, 0)
camera.look_at(item.planet)
camera.rotation = (0, 90, 0)
# import copy
# camera_rotation = copy.deepcopy(camera.rotation)
d = item.planet.scale_x * 20
self.move_camera_to_entity(item.planet, d)
# d = distance(camera.position, item.planet.position)
# camera.look_at(item.planet)
# if d > 1.5 * x:
# move_to = self.move_camera_to_entity(camera.position, item.planet.position, x)
# camera.position = move_to
# camera_rotation = copy.deepcopy(camera.rotation)
# camera.rotation = (camera_rotation[0], camera_rotation[1], 0)
# camera.forward = (1, 0, 0) # 设置相机的方向向量为x轴方向
destroy(self.bodies_button_list)
......@@ -193,11 +235,14 @@ class UrsinaUI:
name = f"{body.name}\t距离:{d:.4f}天文单位"
button_dict[name] = callback_action
else:
if hasattr(self, "bodies_button_list"):
destroy(self.bodies_button_list)
name = f"{body.name}\t距离太远,找不到了"
button_dict[name] = lambda: self.bodies_button_list_click(None)
if hasattr(self, "bodies_button_list"):
destroy(self.bodies_button_list)
self.bodies_button_list = ButtonList(button_dict, font=UrsinaConfig.CN_FONT, button_height=1.5)
# self.bodies_button_list.input = self.bodies_button_list_input
......@@ -235,11 +280,11 @@ class UrsinaUI:
def on_slider_run_speed_changed(self):
UrsinaConfig.run_speed_factor = self.slider_run_speed_factor.value
def show_text_time_scale_info(self):
if self.text_time_scale_info is not None:
self.text_time_scale_info.disable()
text_time_scale = "控制倍率:" + str(application.time_scale).ljust(4, " ")
text_time_scale_info = Text(text=text_time_scale, position=(-0.8, 0.5), origin=(-1, 1), background=True)
# def show_text_time_scale_info(self):
# if self.text_time_scale_info is not None:
# self.text_time_scale_info.disable()
# text_time_scale = "控制倍率:" + str(application.time_scale).ljust(4, " ")
# text_time_scale_info = Text(text=text_time_scale, position=(-0.8, 0.5), origin=(-1, 1), background=True)
# def show_button(self):
# b = Button(scale=(0, .25), text='zzz')
......
......@@ -168,6 +168,14 @@ class UrsinaSimulator(Simulator):
def run(self, dt, **kwargs):
window.title = '宇宙模拟器'
# 设置 camera 的裁剪面和位置
# camera.clip_plane_near = 0.00000009
# camera.fov = 120
# camera.clip_plane_far = 1000
# camera.position = (0, 10, -20)
# camera.rotation_x = -30
# 设定时间间隔为0.01秒
interval = 0.01
self.evolve_dt = dt * interval
......@@ -194,12 +202,6 @@ class UrsinaSimulator(Simulator):
if cosmic_bg is not None and os.path.exists(cosmic_bg):
self.cosmic_background(cosmic_bg)
# 设置 camera 的裁剪面和位置
camera.clip_plane_near = 0.1
# camera.clip_plane_far = 1000
# camera.position = (0, 10, -20)
# camera.rotation_x = -30
ui = UrsinaUI()
EditorCamera(ignore_paused=True)
# 防止打开中文输入法
......
......@@ -47,7 +47,7 @@ class UrsinaPlayer(FirstPersonController):
#
# camera.add_script(SmoothFollow(targets_parent, offset=(0, 8, -20)))
pos = np.array(position) * UrsinaConfig.SCALE_FACTOR
# self.position = Vec3(pos[0], pos[1], pos[2])
self.position = Vec3(pos[0], pos[1], pos[2])
# 将摄像机位置设置为 x=0、y=1、z=0 的位置
camera.position = Vec3(pos[0], pos[1], pos[2])
# self.position = Vec3(pos[0], pos[1], pos[2])
......@@ -95,7 +95,7 @@ class Planet(Entity):
if hasattr(self.body_view.body, "torus_stars"):
# 创建一个星环小天体群(主要模拟小行星群,非一个天体)
model = create_torus(0.86, 1.02, 64, 4)
model = create_torus(0.75, 1.10, 64, 1)
rotation = (90, 0, 0)
else:
# 创建一个天体
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册