Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Python_超人
宇宙模拟器
提交
bda0c387
宇宙模拟器
项目概览
Python_超人
/
宇宙模拟器
通知
19
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
宇宙模拟器
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
bda0c387
编写于
10月 23, 2023
作者:
三月三net
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Python超人-宇宙模拟器
上级
9c7d6f16
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
227 addition
and
3 deletion
+227
-3
sim_scenes/tri_bodies/two_way_foil.py
sim_scenes/tri_bodies/two_way_foil.py
+3
-3
sim_scenes/tri_bodies/two_way_foil_02.py
sim_scenes/tri_bodies/two_way_foil_02.py
+224
-0
未找到文件。
sim_scenes/tri_bodies/two_way_foil.py
浏览文件 @
bda0c387
...
...
@@ -105,9 +105,9 @@ class TwoWayFoilSim:
# 原始的 update 方法中有计算天体的运行
planet
.
init_update
()
# 对Y轴进行压平动画,如果压平大小不足 1/
20,则继续压缩,直到压缩到 1/2
0 就不压缩了
# (如果觉得 1/
2
0 的厚度压的不够,还可以继续压缩,基本上就够了)
if
planet
.
scale_y
>
planet
.
init_scale_y
/
2
0
:
# 对Y轴进行压平动画,如果压平大小不足 1/
50,则继续压缩,直到压缩到 1/5
0 就不压缩了
# (如果觉得 1/
5
0 的厚度压的不够,还可以继续压缩,基本上就够了)
if
planet
.
scale_y
_v
>
planet
.
init_scale_y
/
5
0
:
planet
.
scale_y_v
/=
1.01
# 灯光关闭,不然压到2纬就会是黑色
planet
.
set_light_off
(
True
)
...
...
sim_scenes/tri_bodies/two_way_foil_02.py
0 → 100644
浏览文件 @
bda0c387
# -*- coding:utf-8 -*-
# title :三体二向箔场景模拟
# description :三体二向箔场景模拟
# author :Python超人
# date :2023-10-11
# link :https://gitcode.net/pythoncr/
# python_version :3.9
# ==============================================================================
import
time
from
ursina
import
camera
,
application
from
bodies
import
Sun
,
Mercury
,
Venus
,
Earth
,
Mars
,
Jupiter
,
Saturn
,
Uranus
,
Neptune
,
Pluto
from
common.celestial_data_service
import
get_init_pos_vels
from
common.consts
import
SECONDS_PER_WEEK
,
AU
from
objs
import
QuadObj
,
CircleObj
,
Obj
from
sim_scenes.func
import
camera_look_at
,
two_bodies_colliding
from
sim_scenes.func
import
ursina_run
,
create_sphere_sky
from
simulators.ursina.ursina_event
import
UrsinaEvent
class
TwoWayFoilSim
:
"""
三体二向箔场景模拟
"""
def
__init__
(
self
):
self
.
current_stage
=
self
.
stage_01
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
,
rotate_angle
=
0
),
# 地球放大 4000 倍,距离放大 1.3 倍
Mars
(
size_scale
=
4e3
,
distance_scale
=
1.2
),
# 火星放大 4000 倍,距离放大 1.2 倍
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
=
1.5e3
,
distance_scale
=
0.36
),
# 天王星放大 1500 倍,距离缩小到真实距离的 0.36
Neptune
(
size_scale
=
1.5e3
,
distance_scale
=
0.27
),
# 海王星放大 1500 倍,距离缩小到真实距离的 0.27
Pluto
(
size_scale
=
10e3
,
distance_scale
=
0.23
),
# 冥王星放大 10000 倍,距离缩小到真实距离的 0.23(从太阳系的行星中排除)
]
# endregion
# 获取模拟的初始位置和速度
init_pos_vels
=
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
):
"""
创建二向箔(一个原始的方形二向箔,一个不断扩展的圆形二向箔)
@return:
"""
# 原始的方形二向箔
self
.
two_way_foil
=
QuadObj
(
texture
=
'two_way_foil.png'
,
# size_scale=4e7,
size_scale
=
1e7
,
init_velocity
=
[
0
,
-
6
,
150
],
init_position
=
[
0
,
0.5
*
AU
,
-
10
*
AU
])
\
.
set_light_disable
(
True
).
set_ignore_gravity
(
True
)
# 不断扩展的圆形二向箔
self
.
two_way_foil_circle
=
CircleObj
(
texture
=
"two_way_foil_circle.png"
,
size_scale
=
self
.
two_way_foil
.
size_scale
*
2
,
)
\
.
set_light_disable
(
True
).
set_ignore_gravity
(
True
)
self
.
bodies
.
append
(
self
.
two_way_foil
)
self
.
bodies
.
append
(
self
.
two_way_foil_circle
)
def
build
(
self
):
self
.
build_solar_system
()
self
.
build_two_way_foil
()
def
on_ready
(
self
):
"""
事件绑定后,模拟器运行前会触发
@return:
"""
# 创建天空
# camera.clip_plane_near = 0.1
camera
.
clip_plane_far
=
1000000
create_sphere_sky
(
scale
=
200000
)
application
.
time_scale
=
5
# 圆形二向箔初始化(一开始不显示)
self
.
two_way_foil_circle
.
planet
.
rotation_x
=
90
self
.
two_way_foil_circle
.
planet
.
enabled
=
False
def
flatten_animation
(
self
,
body
):
"""
天体二维化的动画
@param body: 天体
@return:
"""
def
flatten_update
(
planet
):
def
warp
():
# 原始的 update 方法中有计算天体的运行
planet
.
init_update
()
# 对Y轴进行压平动画,如果压平大小不足 1/50,则继续压缩,直到压缩到 1/50 就不压缩了
# (如果觉得 1/50 的厚度压的不够,还可以继续压缩,基本上就够了)
if
planet
.
scale_y_v
>
planet
.
init_scale_y
/
50
:
planet
.
scale_y_v
/=
1.01
planet
.
scale_x_v
+=
0.15
else
:
planet
.
scale_x_v
+=
0.05
# 灯光关闭,不然压到2纬就会是黑色
planet
.
set_light_off
(
True
)
planet
.
scale_y
=
planet
.
scale_y_v
planet
.
scale_x
=
planet
.
scale_x_v
planet
.
scale_z
=
planet
.
scale_x_v
return
warp
# 压平时,转速将为以前的 1/20
body
.
planet
.
rotation_speed
/=
20
# 记录原始的厚度大小
body
.
planet
.
scale_y_v
=
body
.
planet
.
scale_y
body
.
planet
.
init_scale_y
=
body
.
planet
.
scale_y
body
.
planet
.
scale_x_v
=
body
.
planet
.
scale_x
body
.
planet
.
init_scale_x
=
body
.
planet
.
scale_x
# 原始的 update 方法中有计算天体的运行,需要保留
body
.
planet
.
init_update
=
body
.
planet
.
update
# 替换 update
body
.
planet
.
update
=
flatten_update
(
body
.
planet
)
def
stage_01
(
self
):
"""
二向箔飞向太阳
@return:
"""
# 如果二向箔和太阳碰撞
if
two_bodies_colliding
(
self
.
two_way_foil
,
self
.
sun
):
# 隐藏原始二向箔,保持在原地,不在飞行
self
.
two_way_foil
.
planet
.
enabled
=
False
self
.
two_way_foil
.
init_velocity
=
[
0
,
0
,
0
]
# 圆形二向箔显示并设置透明度为0.9
self
.
two_way_foil_circle
.
planet
.
alpha
=
0.9
self
.
two_way_foil_circle
.
planet
.
enabled
=
True
# 当前阶段为 stage_02:二向箔压平天体的阶段
self
.
current_stage
=
self
.
stage_02
def
stage_02
(
self
):
"""
二向箔压平天体(二维化)的阶段
@return:
"""
# self.sun.two_dim.planet.init_scale += 0.05
# 圆形二向箔不断扩展变大
self
.
two_way_foil_circle
.
planet
.
init_scale
+=
0.8
# 调整天体二维化的时间,一般需要延时,保证扩展和二维化同步的真实效果
two_way_delay_times
=
[
0.5
,
# 太阳
0.5
,
0.8
,
1.0
,
# 水星 金星 地球
1.2
,
2.0
,
3.0
,
# 火星 木星 土星
4.0
,
4.5
,
5.5
]
# 天王星 海王星 冥王星
for
idx
,
b
in
enumerate
(
self
.
bodies
):
if
isinstance
(
b
,
Obj
):
# 二向箔不处理
continue
if
hasattr
(
b
,
"two_way_time"
):
# 二向箔和天体碰撞的时间不为空,则说明已经碰撞
if
b
.
two_way_time
is
not
None
:
# 如果碰撞后的延时时间到,则进行压平天体处理(二维化)
if
time
.
time
()
-
b
.
two_way_time
>
two_way_delay_times
[
idx
]:
self
.
flatten_animation
(
b
)
# 二向箔和天体碰撞的时间设置为空,就是说明二维化结束
b
.
two_way_time
=
None
elif
two_bodies_colliding
(
self
.
two_way_foil_circle
,
b
):
# 二向箔和天体碰撞,但暂时先不二维化,记下时间,延时二维化
b
.
two_way_time
=
time
.
time
()
# 圆形二向箔不断旋转的效果
self
.
two_way_foil_circle
.
planet
.
rotation_z
+=
0.4
def
on_timer_changed
(
self
,
time_data
):
"""
@param time_data:
@return:
"""
# 原始方形二向箔飞行的翻转效果
if
self
.
two_way_foil
.
planet
.
enabled
:
self
.
two_way_foil
.
planet
.
rotation_x
+=
0.2
self
.
two_way_foil
.
planet
.
rotation_y
+=
2
# 摄像机始终看向二向箔
camera_look_at
(
self
.
two_way_foil
)
self
.
current_stage
()
if
__name__
==
'__main__'
:
"""
三体二向箔场景模拟
"""
sim
=
TwoWayFoilSim
()
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_WEEK
,
# position=(0, 2 * AU, -11 * AU),
position
=
(
0
,
0.5
*
AU
,
-
5
*
AU
),
cosmic_bg
=
''
,
bg_music
=
'sounds/no_glory.mp3'
,
show_camera_info
=
False
,
show_control_info
=
False
,
timer_enabled
=
True
,
show_grid
=
False
)
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录