Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Python_超人
太阳系三体模拟器
提交
6eb5abae
太阳系三体模拟器
项目概览
Python_超人
/
太阳系三体模拟器
通知
1094
Star
131
Fork
128
代码
文件
提交
分支
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看板
提交
6eb5abae
编写于
3月 19, 2023
作者:
三月三net
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
太阳系三体模拟器
上级
77d1b8e6
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
465 addition
and
67 deletion
+465
-67
bodies/body.py
bodies/body.py
+19
-6
bodies/sun.py
bodies/sun.py
+2
-1
common/system.py
common/system.py
+69
-14
data/gravity_slingshot.json
data/gravity_slingshot.json
+64
-0
data/sun.json
data/sun.json
+29
-14
data/sun_earth.json
data/sun_earth.json
+42
-28
data/sun_earth_moon.json
data/sun_earth_moon.json
+90
-0
data/tri_bodies_sim_perfect_01.json
data/tri_bodies_sim_perfect_01.json
+104
-0
scenes/func.py
scenes/func.py
+10
-1
scenes/gravity_slingshot.py
scenes/gravity_slingshot.py
+1
-1
scenes/sun_earth_moon.py
scenes/sun_earth_moon.py
+1
-1
scenes/ursina_json_sim.py
scenes/ursina_json_sim.py
+33
-0
simulators/ursina/ui/control_handler.py
simulators/ursina/ui/control_handler.py
+1
-1
未找到文件。
bodies/body.py
浏览文件 @
6eb5abae
...
...
@@ -22,7 +22,8 @@ class Body(metaclass=ABCMeta):
def
__init__
(
self
,
name
,
mass
,
init_position
,
init_velocity
,
density
=
5e3
,
color
=
(
125
/
255
,
125
/
255
,
125
/
255
),
texture
=
None
,
size_scale
=
1.0
,
distance_scale
=
1.0
,
rotation_speed
=
None
,
parent
=
None
):
rotation_speed
=
None
,
parent
=
None
,
ignore_mass
=
False
,
is_fixed_star
=
False
):
"""
天体类
:param name: 天体名称
...
...
@@ -35,13 +36,16 @@ class Body(metaclass=ABCMeta):
:param size_scale: 尺寸缩放
:param distance_scale: 距离缩放
:param rotation_speed: 自旋速度(度/小时)
:param parent: 天体的父对象
:param ignore_mass: 是否忽略质量(如果为True,则不计算引力)
:param is_fixed_star: 是否为恒星
"""
self
.
__his_pos
=
[]
self
.
__his_vel
=
[]
self
.
__his_acc
=
[]
self
.
__his_reserved_num
=
200
# 是否忽略质量(如果为True,则不计算引力)
self
.
ignore_mass
=
False
self
.
ignore_mass
=
ignore_mass
if
name
is
None
:
name
=
getattr
(
self
.
__class__
,
'__name__'
)
...
...
@@ -75,6 +79,7 @@ class Body(metaclass=ABCMeta):
# 是否显示
self
.
appeared
=
True
self
.
parent
=
parent
self
.
__is_fixed_star
=
is_fixed_star
@
property
def
init_position
(
self
):
...
...
@@ -126,7 +131,11 @@ class Body(metaclass=ABCMeta):
是否为恒星(太阳为 True)
:return:
"""
return
False
return
self
.
__is_fixed_star
@
is_fixed_star
.
setter
def
is_fixed_star
(
self
,
value
):
self
.
__is_fixed_star
=
value
@
property
def
position
(
self
):
...
...
@@ -340,20 +349,24 @@ class Body(metaclass=ABCMeta):
:return:
"""
bodies
=
[]
with
open
(
json_file
,
"r"
)
as
read_content
:
params
=
{}
with
open
(
json_file
,
"r"
,
encoding
=
'utf-8'
)
as
read_content
:
json_data
=
json
.
load
(
read_content
)
for
body_data
in
json_data
[
"bodies"
]:
# print(body_data)
body
=
Body
(
**
body_data
)
bodies
.
append
(
body
)
if
"params"
in
json_data
:
params
=
json_data
[
"params"
]
# print(body.position_au())
return
bodies
return
bodies
,
params
if
__name__
==
'__main__'
:
# build_bodies_from_json('../data/sun.json')
bodies
=
Body
.
build_bodies_from_json
(
'../data/sun_earth.json'
)
bodies
,
params
=
Body
.
build_bodies_from_json
(
'../data/sun_earth.json'
)
# 太阳半径 / 地球半径
print
(
"太阳半径 / 地球半径 ="
,
bodies
[
0
].
raduis
/
bodies
[
1
].
raduis
)
print
(
"params:"
,
params
)
for
body
in
bodies
:
print
(
body
)
bodies/sun.py
浏览文件 @
6eb5abae
...
...
@@ -21,6 +21,7 @@ class Sun(Body):
def
__init__
(
self
,
name
=
"Sun"
,
mass
=
1.9891e30
,
init_position
=
[
0
,
0
,
0
],
init_velocity
=
[
0
,
0
,
0
],
color
=
(
170
,
98
,
25
),
texture
=
"sun2.jpg"
,
size_scale
=
1.0
,
distance_scale
=
1.0
,
rotation_speed
=
0.6130
):
params
=
{
...
...
@@ -29,7 +30,7 @@ class Sun(Body):
"init_position"
:
init_position
,
"init_velocity"
:
init_velocity
,
"density"
:
1.408e3
,
"color"
:
(
170
,
98
,
25
)
,
"color"
:
color
,
"texture"
:
texture
,
"size_scale"
:
size_scale
,
"distance_scale"
:
distance_scale
,
...
...
common/system.py
浏览文件 @
6eb5abae
...
...
@@ -66,6 +66,36 @@ class System(object):
# body.position += 0.5 * body.acceleration * (dt ** 2)
body
.
position
+=
body
.
velocity
*
dt
def
save_to_json
(
self
,
json_file_name
,
params
=
None
):
"""
:param json_file_name:
:param params:
:return:
"""
import
json
import
os
# json_file = os.path.join("../data", json_file_name)
filed_names
=
[
"name"
,
"mass"
,
"init_position"
,
"init_velocity"
,
"density"
,
"color"
,
"texture"
,
"size_scale"
,
"distance_scale"
,
# "parent"
"rotation_speed"
,
"ignore_mass"
,
"is_fixed_star"
]
bodies
=
[]
for
b
in
self
.
bodies
:
body
=
{}
for
filed_name
in
filed_names
:
filed_value
=
getattr
(
b
,
filed_name
)
if
type
(
filed_value
)
is
np
.
ndarray
:
filed_value
=
filed_value
.
tolist
()
body
[
filed_name
]
=
filed_value
bodies
.
append
(
body
)
data
=
{
"bodies"
:
bodies
}
if
params
is
not
None
:
data
[
"params"
]
=
params
json_str
=
json
.
dumps
(
data
,
indent
=
2
,
ensure_ascii
=
False
,
separators
=
(
','
,
': '
))
with
open
(
json_file_name
,
"w"
,
encoding
=
'utf-8'
)
as
f
:
f
.
write
(
json_str
)
def
calc_bodies_acceleration
(
self
):
"""
计算加速度
...
...
@@ -124,17 +154,42 @@ class System(object):
if
__name__
==
'__main__'
:
body_sys
=
System
([
Sun
(),
# 太阳
Mercury
(),
# 水星
Venus
(),
# 金星
Earth
(),
# 地球
Mars
(),
# 火星
Jupiter
(),
# 木星
Saturn
(),
# 土星
Uranus
(),
# 天王星
Neptune
(),
# 海王星
Pluto
()
# 冥王星(从太阳系的行星中排除)
])
print
(
body_sys
)
# body_sys = System([
# Sun(), # 太阳
# Mercury(), # 水星
# Venus(), # 金星
# Earth(), # 地球
# Mars(), # 火星
# Jupiter(), # 木星
# Saturn(), # 土星
# Uranus(), # 天王星
# Neptune(), # 海王星
# Pluto() # 冥王星(从太阳系的行星中排除)
# ])
import
math
mass
=
2e30
r
=
2
*
AU
# p = 14.9
p
=
14.89
bodies
=
[
Sun
(
name
=
"太阳A红色"
,
mass
=
mass
,
init_position
=
[
0
,
r
*
math
.
sqrt
(
3
),
0
],
# 位置
init_velocity
=
[
-
p
,
0
,
0
],
# 速度(km/s)
size_scale
=
5e1
,
texture
=
"sun2.jpg"
,
color
=
(
255
,
0
,
0
)),
# 太阳放大 100 倍
Sun
(
name
=
"太阳B绿色"
,
mass
=
mass
,
init_position
=
[
-
r
,
0
,
0
],
init_velocity
=
[
1
/
2
*
p
,
-
math
.
sqrt
(
3
)
/
2
*
p
,
0
],
size_scale
=
5e1
,
texture
=
"sun2.jpg"
,
color
=
(
0
,
255
,
0
)),
# 太阳放大 100 倍
Sun
(
name
=
"太阳C蓝色"
,
mass
=
mass
,
init_position
=
[
r
,
0
,
0
],
init_velocity
=
[
1
/
2
*
p
,
math
.
sqrt
(
3
)
/
2
*
p
,
0
],
size_scale
=
5e1
,
texture
=
"sun2.jpg"
,
color
=
(
0
,
0
,
255
)),
# 太阳放大 100 倍
Earth
(
name
=
"地球"
,
# init_position=[0, -AU * -2, 5 * AU],
init_position
=
[
0
,
math
.
sqrt
(
3
)
*
r
/
6
,
5
*
AU
],
init_velocity
=
[
0
,
0
,
-
10
],
size_scale
=
4e3
,
distance_scale
=
1
),
# 地球放大 4000 倍,距离保持不变
]
body_sys
=
System
(
bodies
)
print
(
body_sys
.
save_to_json
(
"../data/tri_bodies_sim_perfect_01.json"
))
data/gravity_slingshot.json
0 → 100644
浏览文件 @
6eb5abae
{
"bodies"
:
[
{
"name"
:
"太阳"
,
"mass"
:
1.9891e+30
,
"init_position"
:
[
0.0
,
0.0
,
0.0
],
"init_velocity"
:
[
0.0
,
0.0
,
0.0
],
"density"
:
1408.0
,
"color"
:
[
170
,
98
,
25
],
"texture"
:
"sun2.jpg"
,
"size_scale"
:
20.0
,
"distance_scale"
:
1.0
,
"rotation_speed"
:
0.613
,
"ignore_mass"
:
false
,
"is_fixed_star"
:
true
},
{
"name"
:
"地球"
,
"mass"
:
5.97237e+24
,
"init_position"
:
[
0.0
,
-448793600.0
,
0.0
],
"init_velocity"
:
[
0.0
,
38.0
,
-1.0
],
"density"
:
5507.85
,
"color"
:
[
1
,
89
,
162
],
"texture"
:
"earth1.jpg"
,
"size_scale"
:
1000.0
,
"distance_scale"
:
1.0
,
"rotation_speed"
:
15
,
"ignore_mass"
:
false
,
"is_fixed_star"
:
false
}
],
"params"
:
{
"dt"
:
2592000
,
"position"
:
[
0
,
149597870.7
,
-448793612.09999996
]
}
}
\ No newline at end of file
data/sun.json
浏览文件 @
6eb5abae
{
"bodies"
:
[
{
{
"name"
:
"太阳"
,
"mass"
:
1.9891e30
,
"mass"
:
1.9891e
+
30
,
"init_position"
:
[
0
,
0
,
0
0
.0
,
0
.0
,
0
.0
],
"init_velocity"
:
[
0
,
0
,
0
0
.0
,
0
.0
,
0
.0
],
"density"
:
1.408e3
,
"color"
:
[
170
,
98
,
25
],
"texture"
:
""
,
"size_scale"
:
1.0
,
"distance_scale"
:
1.0
"density"
:
1408.0
,
"color"
:
[
170
,
98
,
25
],
"texture"
:
"sun2.jpg"
,
"size_scale"
:
50.0
,
"distance_scale"
:
1.0
,
"rotation_speed"
:
0.613
,
"ignore_mass"
:
false
,
"is_fixed_star"
:
true
}
]
],
"params"
:
{
"dt"
:
604800
,
"position"
:
[
0
,
149597870.7
,
-448793612.09999996
]
}
}
\ No newline at end of file
data/sun_earth.json
浏览文件 @
6eb5abae
...
...
@@ -2,49 +2,63 @@
"bodies"
:
[
{
"name"
:
"太阳"
,
"mass"
:
1.9891e30
,
"mass"
:
1.9891e
+
30
,
"init_position"
:
[
0
,
0
,
0
0
.0
,
0
.0
,
0
.0
],
"init_velocity"
:
[
0
,
0
,
0
0
.0
,
0
.0
,
0
.0
],
"density"
:
1
.408e3
,
"density"
:
1
408.0
,
"color"
:
[
1
25
,
125
,
1
25
1
70
,
98
,
25
],
"texture"
:
""
,
"size_scale"
:
1.0
,
"distance_scale"
:
1.0
"texture"
:
"sun2.jpg"
,
"size_scale"
:
50.0
,
"distance_scale"
:
1.0
,
"rotation_speed"
:
0.613
,
"ignore_mass"
:
false
,
"is_fixed_star"
:
true
},
{
"name"
:
"地球"
,
"mass"
:
5.97237e24
,
"mass"
:
5.97237e
+
24
,
"init_position"
:
[
1
49597870.70
0
,
0
,
0
1
67549616.
0
,
0
.0
,
0
.0
],
"init_velocity"
:
[
29.79
,
0
,
0
0.0
,
29.790000915527344
,
0
.0
],
"density"
:
5507.85
,
"color"
:
[
1
25
,
125
,
1
25
1
,
89
,
1
62
],
"texture"
:
""
,
"size_scale"
:
1.0
,
"distance_scale"
:
1.0
"texture"
:
"earth1.jpg"
,
"size_scale"
:
2000.0
,
"distance_scale"
:
1
,
"rotation_speed"
:
15
,
"ignore_mass"
:
false
,
"is_fixed_star"
:
false
}
]
],
"params"
:
{
"dt"
:
604800
,
"position"
:
[
0
,
149597870.7
,
-448793612.09999996
]
}
}
\ No newline at end of file
data/sun_earth_moon.json
0 → 100644
浏览文件 @
6eb5abae
{
"bodies"
:
[
{
"name"
:
"太阳"
,
"mass"
:
1.9891e+30
,
"init_position"
:
[
149597872.0
,
0.0
,
0.0
],
"init_velocity"
:
[
0.0
,
0.0
,
0.0
],
"density"
:
1408.0
,
"color"
:
[
170
,
98
,
25
],
"texture"
:
"sun2.jpg"
,
"size_scale"
:
20.0
,
"distance_scale"
:
1.0
,
"rotation_speed"
:
0.613
,
"ignore_mass"
:
true
,
"is_fixed_star"
:
true
},
{
"name"
:
"地球"
,
"mass"
:
5.97237e+24
,
"init_position"
:
[
0.0
,
0.0
,
0.0
],
"init_velocity"
:
[
0.0
,
0.0
,
0.0
],
"density"
:
5507.85
,
"color"
:
[
1
,
89
,
162
],
"texture"
:
"earth1.jpg"
,
"size_scale"
:
10.0
,
"distance_scale"
:
1.0
,
"rotation_speed"
:
15
,
"ignore_mass"
:
false
,
"is_fixed_star"
:
false
},
{
"name"
:
"月球"
,
"mass"
:
7.342e+22
,
"init_position"
:
[
384400.0
,
0.0
,
0.0
],
"init_velocity"
:
[
0.0
,
1.0230000019073486
,
0.0
],
"density"
:
3344.0
,
"color"
:
[
162
,
162
,
162
],
"texture"
:
"moon.jpg"
,
"size_scale"
:
20.0
,
"distance_scale"
:
1.0
,
"rotation_speed"
:
0.5487
,
"ignore_mass"
:
false
,
"is_fixed_star"
:
false
}
],
"params"
:
{
"dt"
:
86400
,
"position"
:
[
0
,
0
,
0
]
}
}
\ No newline at end of file
data/tri_bodies_sim_perfect_01.json
0 → 100644
浏览文件 @
6eb5abae
{
"bodies"
:
[
{
"name"
:
"红轨太阳A"
,
"mass"
:
2e+30
,
"init_position"
:
[
0.0
,
518222240.0
,
0.0
],
"init_velocity"
:
[
-14.890000343322754
,
0.0
,
0.0
],
"density"
:
1408.0
,
"color"
:
[
255
,
0
,
0
],
"texture"
:
"sun2.jpg"
,
"size_scale"
:
50.0
,
"distance_scale"
:
1.0
},
{
"name"
:
"绿轨太阳B"
,
"mass"
:
2e+30
,
"init_position"
:
[
-299195744.0
,
0.0
,
0.0
],
"init_velocity"
:
[
7.445000171661377
,
-12.895118713378906
,
0.0
],
"density"
:
1408.0
,
"color"
:
[
0
,
255
,
0
],
"texture"
:
"sun2.jpg"
,
"size_scale"
:
50.0
,
"distance_scale"
:
1.0
},
{
"name"
:
"蓝轨太阳C"
,
"mass"
:
2e+30
,
"init_position"
:
[
299195744.0
,
0.0
,
0.0
],
"init_velocity"
:
[
7.445000171661377
,
12.895118713378906
,
0.0
],
"density"
:
1408.0
,
"color"
:
[
0
,
0
,
255
],
"texture"
:
"sun2.jpg"
,
"size_scale"
:
50.0
,
"distance_scale"
:
1.0
},
{
"name"
:
"流浪地球"
,
"mass"
:
5.97237e+24
,
"init_position"
:
[
0.0
,
86370368.0
,
747989376.0
],
"init_velocity"
:
[
0.0
,
0.0
,
-10.0
],
"density"
:
5507.85
,
"color"
:
[
1
,
89
,
162
],
"texture"
:
"earth1.jpg"
,
"size_scale"
:
4000.0
,
"distance_scale"
:
1
}
],
"params"
:
{
"dt"
:
31536000
,
"position"
:
[
0
,
149597870.7
,
-1495978707.0
]
}
}
\ No newline at end of file
scenes/func.py
浏览文件 @
6eb5abae
...
...
@@ -59,7 +59,8 @@ def ursina_run(bodies,
# view_azimuth=0,
light
=
True
,
cosmic_bg
=
None
,
show_grid
=
True
):
show_grid
=
True
,
save_as_json
=
None
):
"""
:param bodies: 天体
...
...
@@ -76,9 +77,17 @@ def ursina_run(bodies,
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
)
if
save_as_json
is
not
None
:
try
:
body_sys
.
save_to_json
(
save_as_json
,
{
"dt"
:
dt
,
"position"
:
position
})
print
(
f
"
{
save_as_json
}
文件生成成功!"
)
except
Exception
as
e
:
print
(
f
"
{
save_as_json
}
文件生成失败!"
+
str
(
e
))
return
simulator
=
UrsinaSimulator
(
body_sys
)
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
...
...
scenes/gravity_slingshot.py
浏览文件 @
6eb5abae
...
...
@@ -32,4 +32,4 @@ if __name__ == '__main__':
# 使用 ursina 查看的运行效果
# position = 左-右+、上+下-、前+后-
# 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹
ursina_run
(
bodies
,
SECONDS_PER_MONTH
,
position
=
(
0
,
AU
,
-
3
*
AU
))
ursina_run
(
bodies
,
SECONDS_PER_MONTH
,
position
=
(
0
,
AU
,
-
3
*
AU
)
,
save_as_json
=
'../data/gravity_slingshot.json'
)
scenes/sun_earth_moon.py
浏览文件 @
6eb5abae
...
...
@@ -43,7 +43,7 @@ if __name__ == '__main__':
# position = 左-右+、上+下-、前+后-
# position=(0, 0, 0) 的位置是站在地球视角,可以观看月相变化的过程
# 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹
ursina_run
(
bodies
,
SECONDS_PER_DAY
,
position
=
(
0
,
0
,
0
))
ursina_run
(
bodies
,
SECONDS_PER_DAY
,
position
=
(
0
,
0
,
0
)
,
save_as_json
=
"../data/sun_earth_moon.json"
)
# 使用 mayavi 查看的运行效果
# mayavi_run(bodies, SECONDS_PER_HALF_DAY / 2, view_azimuth=-45)
scenes/ursina_json_sim.py
0 → 100644
浏览文件 @
6eb5abae
# -*- coding:utf-8 -*-
# title :ursina模拟器(支持天体json文件的读取)
# description :ursina模拟器(支持天体json文件的读取)
# author :Python超人
# date :2023-02-11
# link :https://gitcode.net/pythoncr/
# python_version :3.8
# ==============================================================================
from
bodies
import
Body
from
common.consts
import
SECONDS_PER_WEEK
,
SECONDS_PER_DAY
,
SECONDS_PER_YEAR
,
SECONDS_PER_MONTH
,
AU
from
scenes.func
import
mayavi_run
,
ursina_run
,
mpl_run
if
__name__
==
'__main__'
:
# TODO: 太阳演示
bodies
,
params
=
Body
.
build_bodies_from_json
(
'../data/sun.json'
)
# TODO: 太阳和地球演示
bodies
,
params
=
Body
.
build_bodies_from_json
(
'../data/sun_earth.json'
)
# TODO: 在地球上看月相演示变化过程演示
bodies
,
params
=
Body
.
build_bodies_from_json
(
'../data/sun_earth_moon.json'
)
# TODO: 完美数据的三体模型的演示01
# bodies, params = Body.build_bodies_from_json('../data/tri_bodies_sim_perfect_01.json')
# TODO: 引力弹弓的演示
bodies
,
params
=
Body
.
build_bodies_from_json
(
'../data/gravity_slingshot.json'
)
dt
=
params
[
"dt"
]
if
"dt"
in
params
else
SECONDS_PER_YEAR
position
=
params
[
"position"
]
if
"position"
in
params
else
(
0
,
0
,
0
)
# 使用 ursina 查看的运行效果
# position = 左-右+、上+下-、前+后-
# 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹
json_file
=
None
# 指定 json_file 保存路径,则会将模拟环境天体数据保存到该json文件中
ursina_run
(
bodies
,
dt
,
position
=
position
,
save_as_json
=
json_file
)
simulators/ursina/ui/control_handler.py
浏览文件 @
6eb5abae
...
...
@@ -180,7 +180,7 @@ class ControlHandler(EventHandler):
print
(
key
)
elif
key
==
'y'
:
# 寻找天体
if
hasattr
(
self
,
"bodies_button_list"
):
if
self
.
ui
.
bodies_button_list
.
enabled
:
if
self
.
bodies_button_list
.
enabled
:
self
.
bodies_button_list_close
()
return
self
.
on_searching_bodies_click
()
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录