Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Python_超人
宇宙模拟器
提交
a1947921
宇宙模拟器
项目概览
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看板
提交
a1947921
编写于
10月 28, 2023
作者:
三月三net
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Python超人-宇宙模拟器
上级
7387b622
变更
4
展开全部
显示空白变更内容
内联
并排
Showing
4 changed file
with
613 addition
and
72 deletion
+613
-72
common/celestial_data_service.py
common/celestial_data_service.py
+25
-5
sim_scenes/solar_system/halley_comet_sim_02.py
sim_scenes/solar_system/halley_comet_sim_02.py
+96
-67
simulators/ursina/entities/orbit_line.py
simulators/ursina/entities/orbit_line.py
+449
-0
simulators/ursina/ursina_mesh.py
simulators/ursina/ursina_mesh.py
+43
-0
未找到文件。
common/celestial_data_service.py
浏览文件 @
a1947921
...
...
@@ -14,6 +14,7 @@ from astropy.coordinates import get_body_barycentric_posvel
from
astropy.time
import
Time
from
bodies
import
Body
,
Sun
,
Asteroids
,
Moon
,
Earth
from
common.consts
import
G
,
AU
,
SECONDS_PER_DAY
from
simulators.ursina.ursina_config
import
UrsinaConfig
def
calc_solar_acceleration
(
body_or_pos
,
big_body
):
...
...
@@ -362,6 +363,24 @@ def init_bodies_pos_vels(bodies):
body
.
init_velocity
=
pos_vels
[
'vel'
]
def
get_reality_orbit_points
(
body_name
,
start_time
=
None
,
days
=
365
,
segments
=
100
,
scale_factor
=
1
):
if
start_time
is
None
:
start_time
=
Time
.
now
()
if
days
<
segments
:
s
=
1
else
:
s
=
int
(
round
(
days
/
segments
))
points
=
[]
for
d
in
range
(
0
,
days
,
s
):
dt
=
d
+
start_time
pos
,
vel
=
get_body_barycentric_posvel
(
body_name
,
dt
)
x
,
y
,
z
=
pos
.
x
.
value
*
AU
*
scale_factor
,
pos
.
z
.
value
*
AU
*
scale_factor
,
pos
.
y
.
value
*
AU
*
scale_factor
points
.
append
((
x
,
y
,
z
))
return
points
def
init_bodies_reality_pos_vels
(
bodies
,
dt
=
None
):
from
astropy.coordinates
import
solar_system_ephemeris
as
sse
if
dt
is
None
:
...
...
@@ -398,6 +417,7 @@ def init_bodies_reality_pos_vels(bodies, dt=None):
body
.
init_position
=
pos
body
.
init_velocity
=
vel
if
__name__
==
'__main__'
:
from
astropy.time
import
Time
# 时间
...
...
@@ -421,5 +441,5 @@ if __name__ == '__main__':
# # show_bodies_posvels(dt)
# bs = gen_real_pos_vel_bodies('sun,Mercury,Venus,Earth,Mars,Jupiter,Saturn,Uranus,Neptune',dt)
# print(bs)
print
(
get_init_pos_vels
()[
'sun'
])
print
(
get_reality_orbit_points
(
'earth'
))
#
print(get_init_pos_vels()['sun'])
sim_scenes/solar_system/halley_comet_sim_02.py
浏览文件 @
a1947921
...
...
@@ -11,7 +11,7 @@ import math
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
,
init_bodies_reality_pos_vels
from
common.celestial_data_service
import
get_init_pos_vels
,
init_bodies_reality_pos_vels
,
get_reality_orbit_points
from
common.color_utils
import
trail_color_brightest
from
common.consts
import
SECONDS_PER_YEAR
,
AU
from
common.func
import
calculate_distance
...
...
@@ -21,7 +21,7 @@ from sim_scenes.func import ursina_run, create_sphere_sky
from
simulators.ursina.entities.world_grid
import
WorldGrid
from
simulators.ursina.ursina_config
import
UrsinaConfig
from
simulators.ursina.ursina_event
import
UrsinaEvent
from
simulators.ursina.ursina_mesh
import
create_orbit_line
from
simulators.ursina.ursina_mesh
import
create_orbit_line
,
create_orbit_by_points
class
HalleyCometSim
:
...
...
@@ -34,7 +34,7 @@ class HalleyCometSim:
def
build_solar_system
(
self
):
# region 构建太阳系
show_trail
=
Tru
e
show_trail
=
Fals
e
self
.
sun
=
Sun
(
size_scale
=
0.8e2
,
show_trail
=
show_trail
)
self
.
mercury
=
Mercury
(
size_scale
=
5e3
,
show_trail
=
show_trail
)
self
.
venus
=
Venus
(
size_scale
=
5e3
,
show_trail
=
show_trail
)
...
...
@@ -57,11 +57,20 @@ class HalleyCometSim:
self
.
neptune
,
# 海王星
# self.pluto, # 冥王星
]
self
.
bodies
=
[
self
.
sun
,
# 太阳
self
.
mars
,
# 火星
self
.
neptune
,
# 海王星
]
self
.
mercury
.
orbital_days
=
87.9691
self
.
venus
.
orbital_days
=
224.701
self
.
earth
.
orbital_days
=
365.24219
self
.
mars
.
orbital_days
=
686.971
self
.
jupiter
.
orbital_days
=
11.862
*
365.24219
self
.
saturn
.
orbital_days
=
29.4571
*
365.24219
self
.
uranus
.
orbital_days
=
84.0205
*
365.24219
self
.
neptune
.
orbital_days
=
164.8
*
365.24219
# self.bodies = [
# self.sun, # 太阳
# self.mars, # 火星
# self.neptune, # 海王星
# ]
# endregion
trail_color_brightest
(
self
.
bodies
)
init_bodies_reality_pos_vels
(
self
.
bodies
)
...
...
@@ -88,40 +97,48 @@ class HalleyCometSim:
def
build
(
self
):
self
.
build_solar_system
()
#
self.build_halley_comet()
self
.
build_halley_comet
()
def
calculate_
rotation_
angles
(
self
,
point1
,
point2
):
def
calculate_angles
(
self
,
point1
,
point2
):
dx
=
point2
.
x
-
point1
.
x
dy
=
point2
.
y
-
point1
.
y
dz
=
point2
.
z
-
point1
.
z
roll
=
math
.
atan2
(
dy
,
dz
)
pitch
=
math
.
atan2
(
dx
,
math
.
sqrt
(
dy
**
2
+
dz
**
2
))
yaw
=
math
.
atan2
(
math
.
sin
(
roll
),
math
.
cos
(
roll
))
roll
=
math
.
degrees
(
math
.
atan2
(
dy
,
dz
)
)
pitch
=
math
.
degrees
(
math
.
atan2
(
dx
,
math
.
sqrt
(
dy
**
2
+
dz
**
2
)
))
yaw
=
math
.
degrees
(
math
.
atan2
(
math
.
sin
(
roll
),
math
.
cos
(
roll
)
))
return
roll
,
pitch
,
yaw
def
calculate_angles
(
self
,
point1
,
point2
):
import
numpy
as
np
# 计算向量AB
AB
=
point1
-
point2
# 计算向量AB与x轴、y轴和z轴之间的夹角
angle_x
=
np
.
arctan2
(
AB
.
y
,
AB
.
x
)
*
180
/
np
.
pi
angle_y
=
np
.
arctan2
(
AB
.
z
,
np
.
sqrt
(
AB
.
x
**
2
+
AB
.
y
**
2
))
*
180
/
np
.
pi
angle_z
=
np
.
arctan2
(
np
.
sqrt
(
AB
.
x
**
2
+
AB
.
y
**
2
),
AB
.
z
)
*
180
/
np
.
pi
return
angle_x
,
angle_y
,
angle_z
def
calculate_angles
(
self
,
point1
,
point2
):
#
# def calculate_angles(self, point1, point2):
# import numpy as np
# # 计算向量AB
# AB = point1 - point2
#
# # 计算向量AB与x轴、y轴和z轴之间的夹角
# angle_x = np.arctan2(AB.y, AB.x) * 180 / np.pi
# angle_y = np.arctan2(AB.z, np.sqrt(AB.x ** 2 + AB.y ** 2)) * 180 / np.pi
# angle_z = np.arctan2(np.sqrt(AB.x ** 2 + AB.y ** 2), AB.z) * 180 / np.pi
#
# return angle_x, angle_y, angle_z
# 计算向量AB
AB
=
point2
-
point1
# 计算向量AB与x轴、y轴和z轴之间的夹角
angle_x
=
math
.
degrees
(
math
.
atan2
(
AB
.
z
,
AB
.
y
))
angle_y
=
math
.
degrees
(
math
.
atan2
(
AB
.
z
,
AB
.
x
))
angle_z
=
math
.
degrees
(
math
.
atan2
(
AB
.
y
,
AB
.
x
))
return
angle_x
,
angle_y
,
angle_z
# def calculate_angles(self, point1, point2):
#
# # 计算向量AB
# AB = point2 - point1
# # 计算向量AB与x轴、y轴和z轴之间的夹角
# angle_x = -math.degrees(-math.atan2(AB.z, AB.y))
# angle_y = -math.degrees(-math.atan2(AB.z, AB.x))
# angle_z = math.degrees(math.atan2(AB.y, AB.x))
# return angle_x, angle_y, angle_z
def
create_orbit_line
(
self
,
center_body
,
body
):
orbital_days
=
int
(
math
.
ceil
(
body
.
orbital_days
*
1.02
))
points
=
get_reality_orbit_points
(
type
(
body
).
__name__
.
lower
(),
days
=
orbital_days
,
segments
=
100
)
# print(points)
orbit_line
=
create_orbit_by_points
(
center_body
.
position
,
points
,
line_color
=
body
.
trail_color
)
return
orbit_line
def
on_ready
(
self
):
"""
...
...
@@ -132,16 +149,16 @@ class HalleyCometSim:
from
ursina
import
scene
UrsinaConfig
.
trail_type
=
"line"
UrsinaConfig
.
trail_length
=
91
UrsinaConfig
.
trail_length
=
1000
#
UrsinaConfig.trail_length = 1000
UrsinaConfig
.
trail_thickness_factor
=
3
# camera.clip_plane_near = 0.1
camera
.
clip_plane_far
=
1000000
create_sphere_sky
(
scale
=
200000
)
WorldGrid
().
draw_axises
(
10
)
#
WorldGrid().draw_axises(10)
application
.
time_scale
=
5
self
.
orbit_lines
=
[]
#
self.orbit_lines = []
for
body
in
self
.
bodies
[
1
:]:
if
isinstance
(
body
,
HalleComet
):
continue
...
...
@@ -160,28 +177,42 @@ body.position - sun.position
"""
orbit_line
=
create_orbit_line
(
self
.
sun
,
body
)
angle_x
,
angle_y
,
angle_z
=
self
.
calculate_angles
(
self
.
sun
.
planet
.
position
,
body
.
planet
.
position
)
# # 获取body相对于self.sun的位置向量
# relative_position = body.planet.position - self.sun.planet.position
#
# rotation_x = -math.degrees(
# math.atan2(relative_position.y, math.sqrt(relative_position.x ** 2 + relative_position.z ** 2)))
# rotation_y = math.degrees(math.atan2(relative_position.x, relative_position.z))
# # 计算旋转角度
# orbit_line.rotation_x = rotation_x + 90
# orbit_line.rotation_z = 0
# orbit_line.rotation_y = rotation_y + 120
orbit_line
=
self
.
create_orbit_line
(
self
.
sun
,
body
)
# # orbit_line.enabled = False
# angle_x, angle_y, angle_z = self.calculate_angles(self.sun.planet.position, body.planet.position)
# # # 获取body相对于self.sun的位置向量
# # relative_position = body.planet.position - self.sun.planet.position
# #
# angle = math.atan2(relative_position.y, relative_position.x)
orbit_line
.
rotation_x
=
angle_x
orbit_line
.
rotation_y
=
angle_y
# - 50
orbit_line
.
rotation_z
=
-
angle_z
# # rotation_x = -math.degrees(
# # math.atan2(relative_position.y, math.sqrt(relative_position.x ** 2 + relative_position.z ** 2)))
# # rotation_y = math.degrees(math.atan2(relative_position.x, relative_position.z))
# # # 计算旋转角度
# # orbit_line.rotation_x = rotation_x + 90
# # orbit_line.rotation_z = 0
# # orbit_line.rotation_y = rotation_y + 120
# # #
# # angle = math.atan2(relative_position.y, relative_position.x)
# #
# # orbit_line.rotation_x = angle_x - 110 # angle_x+90 # angle_x # angle_x
# # orbit_line.rotation_y = angle_y # angle_y+90 # angle_y # - 50
# # orbit_line.rotation_z = angle_z - 90 # angle_z# angle_z # angle_z
#
# # print(body.name,angle_x,angle_y,angle_z)
# # print(body.name, orbit_line.rotation_x, orbit_line.rotation_y, orbit_line.rotation_z)
# # orbit_line.look_at(body.planet)
# # print(body.name, orbit_line.rotation_x, orbit_line.rotation_y, orbit_line.rotation_z)
# # 火星 -90.0 -90.0 0.0
# # 火星 -0.0 -0.0 0.0
# # 火星 113.2222958819701 137.6691000401162 -158.65250912389882
# # 火星 16.115840911865234 -132.33090209960938 104.18995666503906
#
# # 海王星 -90.0 -90.0 0.0
# # 海王星 -0.0 -0.0 0.0
# # 海王星 131.3906379192235 3.0188762268681826 -2.6611704409164667
# # 海王星 2.6574795246124268 93.01887512207031 -90.14009857177734
orbit_line
.
body
=
body
self
.
orbit_lines
.
append
(
orbit_line
)
#
orbit_line.body = body
#
self.orbit_lines.append(orbit_line)
self
.
text_panel
=
create_text_panel
()
...
...
@@ -191,7 +222,7 @@ body.position - sun.position
@param time_data:
@return:
"""
if
hasattr
(
self
,
"
self.
halley_comet"
):
if
hasattr
(
self
,
"halley_comet"
):
# 哈雷彗星飞行的翻转效果
if
self
.
halley_comet
.
planet
.
enabled
:
self
.
halley_comet
.
planet
.
rotation_x
+=
0.1
...
...
@@ -201,13 +232,13 @@ body.position - sun.position
d
=
calculate_distance
(
self
.
halley_comet
.
position
,
self
.
sun
.
position
)
self
.
text_panel
.
text
=
"哈雷彗星距离太阳:%.3f AU"
%
(
d
/
AU
)
for
i
,
orbit_line
in
enumerate
(
self
.
orbit_lines
):
if
i
<
4
:
adj_scale
=
False
else
:
adj_scale
=
True
# 由于天体运行不是标准的圆形,则需要动态调整轨道的大小,保证轨道线始终在天体的中心位置
orbit_line
.
auto_adjust
(
adj_scale
=
adj_scale
)
#
for i, orbit_line in enumerate(self.orbit_lines):
#
if i < 4:
#
adj_scale = False
#
else:
#
adj_scale = True
#
# 由于天体运行不是标准的圆形,则需要动态调整轨道的大小,保证轨道线始终在天体的中心位置
#
orbit_line.auto_adjust(adj_scale=adj_scale)
if
__name__
==
'__main__'
:
...
...
@@ -217,8 +248,6 @@ if __name__ == '__main__':
sim
=
HalleyCometSim
()
sim
.
build
()
# 订阅事件后,上面2个函数功能才会起作用
# 运行中,每时每刻都会触发 on_timer_changed
UrsinaEvent
.
on_timer_changed_subscription
(
sim
.
on_timer_changed
)
...
...
simulators/ursina/entities/orbit_line.py
0 → 100644
浏览文件 @
a1947921
此差异已折叠。
点击以展开。
simulators/ursina/ursina_mesh.py
浏览文件 @
a1947921
...
...
@@ -17,6 +17,7 @@ import math
from
common.color_utils
import
conv_to_vec4_color
from
common.func
import
calculate_distance
from
simulators.ursina.entities.circle_line
import
CircleLine
from
simulators.ursina.entities.orbit_line
import
OrbitLine
from
simulators.ursina.ursina_config
import
UrsinaConfig
...
...
@@ -136,6 +137,22 @@ def create_circle_line(parent=None, radius=1, position=None, segments=100, thick
return
circle_line
def
create_orbit_line
(
parent
=
None
,
position
=
None
,
points
=
100
,
thickness
=
0.1
,
color
=
color
.
white
,
alpha
=
1
):
if
isinstance
(
color
,
tuple
)
or
isinstance
(
color
,
list
):
color
=
conv_to_vec4_color
(
color
)
if
alpha
<
1
:
color
[
3
]
=
alpha
orbit_line
=
OrbitLine
(
position
=
position
,
points
=
points
,
thickness
=
thickness
,
color
=
color
,
alpha
=
alpha
)
orbit_line
.
set_light_off
(
True
)
if
parent
is
not
None
:
if
hasattr
(
parent
,
"planet"
):
parent
=
parent
.
planet
orbit_line
.
parent
=
parent
return
orbit_line
def
create_arrow_line
(
from_pos
,
to_pos
,
parent
=
None
,
label
=
None
,
set_light_off
=
True
,
alpha
=
1.0
,
len_scale
=
0.5
,
color
=
color
.
white
,
thickness
=
2
,
...
...
@@ -263,6 +280,32 @@ def create_orbit_line(center_obj, orbiting_obj, thickness=5, line_color=None, al
return
orbit_line
def
create_orbit_by_points
(
center_pos
,
orbiting_points
,
thickness
=
5
,
line_color
=
color
.
white
,
alpha
=
0.6
,
scale_factor
=
None
):
if
isinstance
(
line_color
,
tuple
)
or
isinstance
(
line_color
,
list
):
line_color
=
conv_to_vec4_color
(
line_color
)
if
alpha
<
1
:
line_color
[
3
]
=
alpha
if
scale_factor
is
None
:
scale_factor
=
UrsinaConfig
.
SCALE_FACTOR
if
scale_factor
!=
1
:
center_pos
=
center_pos
*
scale_factor
for
i
,
point
in
enumerate
(
orbiting_points
):
orbiting_points
[
i
]
=
np
.
array
([
point
[
0
]
*
scale_factor
,
point
[
1
]
*
scale_factor
,
point
[
2
]
*
scale_factor
])
orbit_line
=
OrbitLine
(
points
=
orbiting_points
,
position
=
center_pos
,
thickness
=
thickness
,
color
=
line_color
,
alpha
=
alpha
)
orbit_line
.
set_light_off
(
True
)
# if parent is not None:
# if hasattr(parent, "planet"):
# parent = parent.planet
# circle_line.parent = parent
return
orbit_line
def
create_orbit_line2
(
center_obj
,
orbiting_obj
,
line_color
=
color
.
white
,
alpha
=
0.3
):
if
isinstance
(
line_color
,
tuple
)
or
isinstance
(
line_color
,
list
):
line_color
=
color
.
rgba
(
line_color
[
0
]
/
255
,
line_color
[
1
]
/
255
,
line_color
[
2
]
/
255
,
alpha
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录