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

太阳系三体模拟器

上级 e2a28818
......@@ -55,22 +55,37 @@ def mayavi_run(bodies, dt=SECONDS_PER_WEEK,
def ursina_run(bodies,
dt=SECONDS_PER_HALF_DAY,
position=(4000000, 800000000, 4000000),
# view_azimuth=0,
light=True,
cosmic_bg=None,
show_grid=True):
"""
:param bodies:
:param dt:
:param bodies: 天体
:param dt: 单位:秒,按时间差进行演变,值越小越精确,但演变速度会慢。
:param position: 摄像头位置
:param view_azimuth: 摄像头观测方位角,可选,float类型(以度为单位,0-360)
:param light: 使用灯光效果
:param cosmic_bg: 宇宙背景图片
:param show_grid: 是否显示空间网格
:return:
"""
from simulators.ursina_simulator import UrsinaSimulator, UrsinaPlayer
from ursina import application, Sequence, camera, held_keys, time, clamp,Entity,Text
from ursina import application, Sequence, camera, held_keys, time, clamp, Entity, Text, color
from ursina.prefabs.first_person_controller import FirstPersonController
body_sys = System(bodies)
simulator = UrsinaSimulator(body_sys)
player = UrsinaPlayer(position, simulator.ursina_views)
view_azimuth = 0 # 暂时未用
player = UrsinaPlayer(position, view_azimuth, simulator.ursina_views)
# # player = FirstPersonController(model='cube', y=-1e20, color=color.orange, origin_y=-5000, speed=8)
# # player.on_disable()
# # player.position = position
#
# player = FirstPersonController()
# cube = Entity(model='cube', color=color.red, scale=2)
# player.parent = cube # 设置 FirstPersonController 的父实体为 cube
# cube.position = position # 修改父实体的位置,从而间接地修改 FirstPersonController 的位置
# # 创建一个实体(在屏幕中央)和一个摄像机
# TODO: 未使用
......
......@@ -39,4 +39,5 @@ if __name__ == '__main__':
# mayavi_run(bodies, SECONDS_PER_WEEK, view_azimuth=-45)
# 使用 ursina 查看的运行效果
ursina_run(bodies, SECONDS_PER_YEAR, position=(0, 5 * AU, -10 * AU)) # position=左-右+、上+下-、前+后-
# position = 左-右+、上+下-、前+后-
ursina_run(bodies, SECONDS_PER_YEAR, position=(0, 2 * AU, -11 * AU))
......@@ -7,7 +7,7 @@
# python_version :3.8
# ==============================================================================
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
from common.consts import SECONDS_PER_WEEK, SECONDS_PER_DAY, SECONDS_PER_MONTH, SECONDS_PER_YEAR, AU
from scenes.func import mayavi_run, ursina_run
if __name__ == '__main__':
......@@ -42,4 +42,5 @@ if __name__ == '__main__':
# mayavi_run(bodies, SECONDS_PER_WEEK, view_azimuth=-45, view_distance=3e9, view_focalpoint=[5e2, 5e2, 5e2])
# 使用 ursina 查看的运行效果
ursina_run(bodies, SECONDS_PER_YEAR, position=(0, 0, 0))
\ No newline at end of file
# position = 左-右+、上+下-、前+后-
ursina_run(bodies, SECONDS_PER_YEAR, position=(0, 2 * AU, -11 * AU))
......@@ -7,7 +7,7 @@
# python_version :3.8
# ==============================================================================
from bodies import Sun, Earth
from common.consts import SECONDS_PER_WEEK, SECONDS_PER_DAY
from common.consts import SECONDS_PER_WEEK, SECONDS_PER_DAY, AU
from scenes.func import mayavi_run, ursina_run
if __name__ == '__main__':
......@@ -23,4 +23,5 @@ if __name__ == '__main__':
# mayavi_run(bodies, SECONDS_PER_WEEK, view_azimuth=-45)
# 使用 ursina 查看的运行效果
ursina_run(bodies, SECONDS_PER_WEEK, position=(0, 0, 0))
# position = 左-右+、上+下-、前+后-
ursina_run(bodies, SECONDS_PER_WEEK, position=(0, AU, -3 * AU))
......@@ -7,7 +7,7 @@
# python_version :3.8
# ==============================================================================
from bodies import Sun, Earth, Jupiter
from common.consts import SECONDS_PER_WEEK
from common.consts import SECONDS_PER_WEEK, AU
from scenes.func import mayavi_run, ursina_run
if __name__ == '__main__':
......@@ -24,4 +24,5 @@ if __name__ == '__main__':
# mayavi_run(bodies, SECONDS_PER_WEEK, view_azimuth=-45)
# 使用 ursina 查看的运行效果
ursina_run(bodies, SECONDS_PER_WEEK, position=(0, 0, 0))
# position = 左-右+、上+下-、前+后-
ursina_run(bodies, SECONDS_PER_WEEK, position=(0, AU, -3 * AU))
......@@ -20,17 +20,28 @@ if __name__ == '__main__':
sun = Sun(init_position=[AU, 0, 0], size_scale=2e1) # 太阳放大 20 倍
# 忽略质量的引力
sun.ignore_mass = True
# 观看月相变化的过程:分别是 新月、蛾眉月、上弦月、盈凸、满月、亏凸、下弦月、残月
# TODO: 月球在摄像机的前方(从 “新月” 开始)
moon_pos, moon_vel = [384400, 0, 0], [0, EARTH_INIT_VELOCITY + 1.023, 0]
# TODO: 月球在摄像机的右方(从 “下弦月” 开始),将会出现
# moon_pos, moon_vel = [0, -384400, 0], [1.023, EARTH_INIT_VELOCITY, 0]
# TODO: 月月球在摄像机的左方(从 “上弦月” 开始)
# moon_pos, moon_vel = [0, 384400, 0], [-1.023, EARTH_INIT_VELOCITY, 0]
bodies = [
sun,
Earth(init_position=[0, 0, 0],
init_velocity=[0, EARTH_INIT_VELOCITY, 0],
size_scale=1e1), # 地球放大 10 倍,距离保持不变
Moon(init_position=[0, 384400, 0], # 距地距离约: 363104 至 405696 km
init_velocity=[-1.023, EARTH_INIT_VELOCITY, 0],
size_scale=2e1) # 月球放大 20 倍,距离保持不变
size_scale=1e1), # 地球放大 10 倍,距离保持不变
Moon(init_position=moon_pos, # 距地距离约: 363104 至 405696 km
init_velocity=moon_vel,
size_scale=2e1) # 月球放大 20 倍,距离保持不变
]
# 使用 mayavi 查看的运行效果
# mayavi_run(bodies, SECONDS_PER_HALF_DAY / 2, view_azimuth=-45)
# 使用 ursina 查看的运行效果
# position = 左-右+、上+下-、前+后-
# position=(0, 0, 0) 的位置是站在地球视角,可以观看月相变化的过程
ursina_run(bodies, SECONDS_PER_DAY, position=(0, 0, 0))
......@@ -7,7 +7,7 @@
# python_version :3.8
# ==============================================================================
from bodies import Sun, Earth
from common.consts import SECONDS_PER_WEEK, SECONDS_PER_DAY
from common.consts import SECONDS_PER_WEEK, SECONDS_PER_DAY, AU
from scenes.func import mayavi_run, ursina_run
if __name__ == '__main__':
......@@ -32,4 +32,5 @@ if __name__ == '__main__':
# mayavi_run(bodies, SECONDS_PER_WEEK, view_azimuth=0)
# 使用 ursina 查看的运行效果
ursina_run(bodies, SECONDS_PER_DAY, position=(0, 0, 0))
\ No newline at end of file
# position = 左-右+、上+下-、前+后-
ursina_run(bodies, SECONDS_PER_DAY, position=(3 * AU, AU, -4 * AU))
\ No newline at end of file
......@@ -7,7 +7,7 @@
# python_version :3.8
# ==============================================================================
from bodies import Sun, Earth
from common.consts import SECONDS_PER_DAY, SECONDS_PER_WEEK, SECONDS_PER_YEAR
from common.consts import SECONDS_PER_DAY, SECONDS_PER_WEEK, SECONDS_PER_YEAR, AU
from scenes.func import mayavi_run, mpl_run, ursina_run
if __name__ == '__main__':
......@@ -57,4 +57,5 @@ if __name__ == '__main__':
# mpl_run(bodies, SECONDS_PER_WEEK)
# 使用 ursina 查看的运行效果
ursina_run(bodies, SECONDS_PER_YEAR, position=(0, 0, 0))
# position = 左-右+、上+下-、前+后-
ursina_run(bodies, SECONDS_PER_YEAR, position=(3 * AU, 3 * AU, -20 * AU))
......@@ -7,8 +7,8 @@
# python_version :3.8
# ==============================================================================
from bodies import Sun, Earth
from common.consts import SECONDS_PER_WEEK
from scenes.func import mayavi_run
from common.consts import SECONDS_PER_WEEK, SECONDS_PER_YEAR, AU
from scenes.func import mayavi_run, mpl_run, ursina_run
if __name__ == '__main__':
"""
......@@ -28,4 +28,8 @@ if __name__ == '__main__':
]
# 使用 mayavi 查看的运行效果
mayavi_run(bodies, SECONDS_PER_WEEK, view_azimuth=0)
# mayavi_run(bodies, SECONDS_PER_WEEK, view_azimuth=0)
# 使用 ursina 查看的运行效果
# position = 左-右+、上+下-、前+后-
ursina_run(bodies, SECONDS_PER_YEAR, position=(0, 2 * AU, -5 * AU))
\ No newline at end of file
......@@ -12,7 +12,8 @@
class UrsinaConfig:
# 常量定义
# 天体缩放的因子(不能太大,否则无法容得下大数量级的天体)调整 5e-7 最佳
SCALE_FACTOR = 5e-7
__SCALE_FACTOR = 5e-7
auto_scale_factor = 1.0 # __SCALE_FACTOR 不能满足,需要自动进行调整
# 旋转因子为1,则为正常的转速
ROTATION_SPEED_FACTOR = 1.0
# ROTATION_SPEED_FACTOR = 0.01
......@@ -34,7 +35,7 @@ class UrsinaConfig:
show_trail = False
# 拖尾球体的数量
trail_length = 200
trail_length = 100
# 默认秒数(0表示默认)
seconds_per = 0
# # 控制摄像机动作速度(天体越大,速度越快,天体越小,速度越慢)
......@@ -42,6 +43,25 @@ class UrsinaConfig:
__body_size_factor = 1.0
@classmethod
def init(cls):
# 初始化
cls.run_speed_factor = 1.0
cls.body_spin_factor = 1.0
cls.body_size_factor = 1.0
# 天体缩放的因子(不能太大,否则无法容得下大数量级的天体)调整 5e-7 最佳
cls.SCALE_FACTOR = 5e-7
@property
@classmethod
def SCALE_FACTOR(cls):
return cls.__SCALE_FACTOR * cls.auto_scale_factor
@SCALE_FACTOR.setter
@classmethod
def SCALE_FACTOR(cls, value):
cls.__SCALE_FACTOR = value
@property
@classmethod
def run_speed_factor(cls):
......@@ -82,10 +102,7 @@ class UrsinaConfig:
f()
# 初始化
UrsinaConfig.run_speed_factor = 1.0
UrsinaConfig.body_spin_factor = 1.0
UrsinaConfig.body_size_factor = 1.0
UrsinaConfig.init()
if __name__ == '__main__':
UrsinaConfig.run_speed_factor = 2.0
......
......@@ -29,9 +29,9 @@ class UrsinaUI:
# application.time_scale = 0.5
self.slider_body_spin_factor = UiSlider(text='自转速度', min=0.01, max=30, default=1)
self.slider_body_size_factor = UiSlider(text='天体缩放', min=0.1, max=100, default=1)
self.slider_body_size_factor = UiSlider(text='天体缩放', min=0.1, max=100, step=0.1, default=1)
self.slider_run_speed_factor = UiSlider(text="运行速度", min=0.01, max=80, default=1)
self.slider_control_speed_factor = UiSlider(text="控制速度", min=0.01, max=50, default=application.time_scale)
self.slider_control_speed_factor = UiSlider(text="控制速度", min=0.01, max=20, default=application.time_scale)
self.slider_trail_length = UiSlider(text="拖尾长度", min=30, max=500, step=10, default=UrsinaConfig.trail_length)
self.slider_body_size_factor.on_value_changed = self.on_slider_body_size_changed
......@@ -98,7 +98,7 @@ class UrsinaUI:
)
self.sec_per_time_switch.x = -0.4
self.on_off_switch.x = 0.2
self.on_off_trail.x = -0.4
self.on_off_trail.x = 0.2 # -0.4
wp.y = 0.5 # wp.panel.scale_y / 2 * wp.scale_y # center the window panel
wp.x = 0.6 # wp.scale_x + 0.1
# wp.x = 0#wp.panel.scale_x / 2 * wp.scale_x
......
......@@ -57,10 +57,10 @@ class UrsinaSimulator(Simulator):
self.ursina_views.append(view)
# planets.append(newPlanet)
# x += cp[i] * 10
self.adj_application_time_scale()
self.adj_run_params()
UrsinaEvent.on_searching_bodies_subscription(type(self).__name__, self.on_searching_bodies)
def adj_application_time_scale(self):
def adj_run_params(self):
max_distance = 0
for b1 in self.body_views:
for b2 in self.body_views:
......@@ -71,10 +71,12 @@ class UrsinaSimulator(Simulator):
max_distance = d
# UrsinaConfig.control_camera_speed = round(max_distance * 10, 2)
time_scale = round(pow(max_distance, 1 / 3), 2)
time_scale = round(pow(max_distance, 1 / 4), 2)
if time_scale < 0.01:
time_scale = 0.01
application.time_scale = time_scale
# UrsinaConfig.auto_scale_factor = 1.0e-9
def on_searching_bodies(self, **kwargs):
views = []
......
......@@ -28,9 +28,9 @@ class UrsinaPlayer(FirstPersonController):
"""
"""
body_rotation_speed_control = 1.0
# body_rotation_speed_control = 1.0
def __init__(self, position, targets=None):
def __init__(self, position, view_azimuth=0, targets=None):
super().__init__()
# camera.fov = 2000 # 100
# camera.rotation_y = 90
......@@ -50,18 +50,21 @@ class UrsinaPlayer(FirstPersonController):
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.x = 90
# self.position = Vec3(pos[0], pos[1], pos[2])
# 将摄像机的观察角度绕 x 轴旋转 45 度,绕 y 轴旋转 0 度,绕 z 轴旋转 0 度
# camera.rotation = Vec3(45, 90, 0)
camera.rotation = Vec3(0, 0, 0)
# self.rotation = Vec3(45, 90, 0)
# camera.look_at(Vec3(0, 0, 0))
# camera.world_rotation = Vec3(0, 190, 190)
# camera.enabled = True
# self.gravity = 0
# self.vspeed = 400
# self.speed = 1000
# self.mouse_sensitivity = Vec2(160, 160)
# self.on_enable()
# self.rotation_speed = 80
self.on_disable()
self.on_disable() # 防止鼠标被窗口锁定
# def input(self, key):
# if key == "escape":
......@@ -95,7 +98,7 @@ class Planet(Entity):
if hasattr(self.body_view.body, "torus_stars"):
# 创建一个星环小天体群(主要模拟小行星群,非一个天体)
model = create_torus(0.75, 1.10, 64, 1)
model = create_torus(0.83, 1.05, 64, 1)
rotation = (90, 0, 0)
else:
# 创建一个天体
......@@ -112,11 +115,12 @@ class Planet(Entity):
color=color.white,
position=pos,
rotation=rotation # ,double_sided=True
)
)
if hasattr(self.body_view.body, "torus_stars"):
# 星环小天体群(主要模拟小行星群,非一个天体)
self.set_light_off()
self.double_sided = True
else:
# 一个天体
# 拖尾球体的初始化
......@@ -195,8 +199,12 @@ class Planet(Entity):
:param pos:
:return:
"""
trail = Entity(model="sphere", color=self.trail_color, scale=self.trail_scale, position=pos)
# sphere = create_sphere(1,6) diamond sphere
trail = Entity(model='sphere', color=self.trail_color, scale=self.trail_scale, position=pos)
trail.set_light_off()
# trail.set_color_off()
# trail.set_color_scale_off()
# trail.enabled = False
return trail
def turn(self):
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册