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

Python超人-宇宙模拟器

上级 1cf04e66
...@@ -8,28 +8,29 @@ ...@@ -8,28 +8,29 @@
# ============================================================================== # ==============================================================================
from bodies import Sun, Earth, Jupiter, Mars, Venus from bodies import Sun, Earth, Jupiter, Mars, Venus
from common.consts import SECONDS_PER_YEAR, SECONDS_PER_MONTH, AU from common.consts import SECONDS_PER_YEAR, SECONDS_PER_MONTH, AU
from sim_scenes.func import mayavi_run, ursina_run, camera_look_at from sim_scenes.func import ursina_run, camera_look_at
from simulators.ursina.entities.body_timer import TimeData from simulators.ursina.entities.body_timer import TimeData
from simulators.ursina.ursina_config import UrsinaConfig from simulators.ursina.ursina_config import UrsinaConfig
from simulators.ursina.ursina_event import UrsinaEvent from simulators.ursina.ursina_event import UrsinaEvent
from simulators.ursina.ursina_mesh import create_line from simulators.ursina.ursina_mesh import create_connecting_line
from ursina import color
if __name__ == '__main__': if __name__ == '__main__':
""" """
与木星跳舞 与木星跳舞
""" """
# 选择舞者 # 选择舞者
Dancer = Earth # 舞者为地球 # Dancer = Earth # 舞者为地球
Dancer = Venus # 舞者为金星 # Dancer = Mars # 舞者为火星
Dancer = Mars # 舞者为火星
bodies = [ sun = Sun(size_scale=0.8e2) # 太阳放大 80 倍
Sun(size_scale=0.8e2), # 太阳放大 80 倍 jupiter = Jupiter(size_scale=5e2) # 木星放大 500 倍
Dancer(size_scale=5e3), # 舞者放大 5000 倍 bodies = [sun, jupiter]
Jupiter(size_scale=5e2), # 木星放大 500 倍
] dancers = [Earth(size_scale=5e3), Mars(size_scale=5e3)] # 两个舞者放大 5000 倍
sun, dancer, jupiter = bodies[0], bodies[1], bodies[2] dancers = [Earth(size_scale=5e3)] # 舞者为地球,放大 5000 倍
dancers = [Mars(size_scale=5e3)] # 舞者为火星,放大 5000 倍
bodies = bodies + dancers
def on_ready(): def on_ready():
...@@ -41,7 +42,10 @@ if __name__ == '__main__': ...@@ -41,7 +42,10 @@ if __name__ == '__main__':
def on_timer_changed(time_data: TimeData): def on_timer_changed(time_data: TimeData):
if int(time_data.total_days) % 10 == 0: if int(time_data.total_days) % 10 == 0:
create_line(from_pos=jupiter.planet.position, to_pos=dancer.planet.main_entity.position, color=color.white) for dancer in dancers:
line_color = dancer.color
line_color = (255, 255, 100)
create_connecting_line(jupiter, dancer, line_color=line_color)
# 订阅事件后,上面2个函数功能才会起作用 # 订阅事件后,上面2个函数功能才会起作用
......
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*-
# title :拉格朗日点模拟 # title :地月拉格朗日点模拟
# description :拉格朗日点模拟 # description :地月拉格朗日点模拟(理想的拉格朗日点位置)
# author :Python超人 # author :Python超人
# date :2023-02-11 # date :2023-05-01
# link :https://gitcode.net/pythoncr/ # link :https://gitcode.net/pythoncr/
# python_version :3.8 # python_version :3.8
# ============================================================================== # ==============================================================================
from bodies import Body, Sun, Earth, Moon from bodies import Earth, Moon
from objs import Obj, Satellite, Satellite2 from objs import Satellite, Satellite2
from common.consts import SECONDS_PER_HOUR, SECONDS_PER_DAY, SECONDS_PER_WEEK, SECONDS_PER_MONTH from common.consts import SECONDS_PER_HOUR, SECONDS_PER_DAY, SECONDS_PER_WEEK, SECONDS_PER_MONTH
from sim_scenes.func import ursina_run, camera_look_at from sim_scenes.func import ursina_run, camera_look_at
from simulators.ursina.entities.body_timer import TimeData from simulators.ursina.entities.body_timer import TimeData
from simulators.ursina.entities.entity_utils import create_directional_light
from simulators.ursina.ursina_event import UrsinaEvent from simulators.ursina.ursina_event import UrsinaEvent
from simulators.ursina.ursina_mesh import create_line from simulators.ursina.ursina_mesh import create_connecting_lines
import math import math
bodies = [
Earth(init_position=[0, 0, 0], texture="earth_hd.jpg",
init_velocity=[0, 0, 0], size_scale=0.5e1), # 地球放大 5 倍,距离保持不变
Moon(init_position=[0, 0, 363104], # 距地距离约: 363104 至 405696 km
init_velocity=[-1.054152222, 0, 0], size_scale=1e1) # 月球放大 10 倍,距离保持不变
]
earth = bodies[0]
moon = bodies[1]
def get_lagrangian_points(m1, m2, r): def get_lagrangian_points(m1, m2, r):
""" """
用于计算理想的拉格朗日点
@param m1: 大质量 @param m1: 大天体的质量
@param m2: 小质量 @param m2: 小天体的质量
@param r: 半径 @param r: 小天体绕大天体的半径
@return: @return: 返回拉格朗日点 L1, L2, L3, L4, L5 的坐标
""" """
a = m2 / (m1 + m2) a = m2 / (m1 + m2)
l1 = (0, 0, r * (1 - pow(a / 3, 1 / 3))) l1 = (0, 0, r * (1 - pow(a / 3, 1 / 3)))
...@@ -45,65 +34,53 @@ def get_lagrangian_points(m1, m2, r): ...@@ -45,65 +34,53 @@ def get_lagrangian_points(m1, m2, r):
return l1, l2, l3, l4, l5 return l1, l2, l3, l4, l5
# 计算地月拉格朗日点 # 月球绕地球的半径
L1_p, L2_p, L3_p, L4_p, L5_p = get_lagrangian_points(earth.mass, moon.mass, 363104) R = 363104
# 创建地月
earth = Earth(init_position=[0, 0, 0], texture="earth_hd.jpg",
init_velocity=[0, 0, 0], size_scale=0.8e1) # 地球放大 8 倍,地月距离保持不变
moon = Moon(init_position=[0, 0, R], # 距地距离约: 363104 至 405696 km
init_velocity=[-1.054152222, 0, 0], size_scale=1.2e1) # 月球放大 12 倍,地月距离保持不变
# 获取地月拉格朗日点(理想数据)
L1_p, L2_p, L3_p, L4_p, L5_p = get_lagrangian_points(earth.mass, moon.mass, R)
# region 在拉格朗日点 L1, L2, L3, L4, L5 上创建卫星
def create_satellite(name, init_position, init_velocity): def create_satellite(name, init_position, init_velocity):
""" """
L1, L2, L3, L4, L5 创建卫星 指定位置创建卫星,并给予卫星一个初速度
@param name: @param name: 卫星名称
@param init_position: @param init_position: 初始位置
@param init_velocity: @param init_velocity: 初始速度
@return: @return:
""" """
satellite = Satellite(name=name, mass=1.4e10, size_scale=4e3, color=(255, 200, 0), satellite = Satellite(name=name, mass=1.4e10, size_scale=2e3, color=(255, 200, 0),
init_position=init_position, init_position=init_position,
init_velocity=init_velocity, gravity_only_for=[earth, moon]) init_velocity=init_velocity, gravity_only_for=[earth, moon])
return satellite return satellite
# L1:point=[0,0,308536.70059015526] velocity=[-0.890136271716, 0, 0] # 在 L1 位置上创建一个具有初速度的卫星
satelliteL1 = create_satellite(name=f'卫星L1', init_position=L1_p, satelliteL1 = create_satellite(name=f'卫星L1', init_position=L1_p,
init_velocity=[-0.890136271716, 0, 0]) init_velocity=[-0.890136271716, 0, 0])
bodies.append(satelliteL1) # 在 L2 位置上创建一个具有初速度的卫星
# L2:point=[0,0, 423338.5083198447] velocity=[-1.24, 0, 0]
satelliteL2 = create_satellite(name=f'卫星L2', init_position=L2_p, satelliteL2 = create_satellite(name=f'卫星L2', init_position=L2_p,
init_velocity=[-1.24, 0, 0]) init_velocity=[-1.24, 0, 0])
bodies.append(satelliteL2)
vel_L345 = 1.048 vel_L345 = 1.048
# L3:point=[0,0, -364941.3043941873] velocity=[1.039 , 0, 0] # 在 L3 位置上创建一个具有初速度的卫星
satelliteL3 = create_satellite(name=f'卫星L3', init_position=L3_p, satelliteL3 = create_satellite(name=f'卫星L3', init_position=L3_p,
init_velocity=[vel_L345, 0, 0]) init_velocity=[vel_L345, 0, 0])
bodies.append(satelliteL3) # 在 L4 位置上创建一个具有初速度的卫星
# L4:point=[0,0, 177142.46945395062] velocity=[1.039 , 0, 0]
satelliteL4 = create_satellite(name=f'卫星L4', init_position=L4_p, satelliteL4 = create_satellite(name=f'卫星L4', init_position=L4_p,
init_velocity=[-math.sin(math.pi * 30 / 180) * vel_L345, 0, init_velocity=[-math.sin(math.pi * 30 / 180) * vel_L345, 0,
math.cos(math.pi * 30 / 180) * vel_L345]) math.cos(math.pi * 30 / 180) * vel_L345])
bodies.append(satelliteL4) # 在 L5 位置上创建一个具有初速度的卫星
# L5:point=[0,0, 177142.46945395062] velocity=[1.039 , 0, 0]
satelliteL5 = create_satellite(name=f'卫星L5', init_position=L5_p, satelliteL5 = create_satellite(name=f'卫星L5', init_position=L5_p,
init_velocity=[-math.sin(math.pi * 30 / 180) * vel_L345, 0, init_velocity=[-math.sin(math.pi * 30 / 180) * vel_L345, 0,
-math.cos(math.pi * 30 / 180) * vel_L345]) -math.cos(math.pi * 30 / 180) * vel_L345])
bodies.append(satelliteL5) # endregion
def create_connecting_lines(satellites_list):
"""
创建连接线(将卫星列表用线条连接起来)
@param satellites_list:
@return:
"""
lines = []
for satellites in satellites_list:
line = create_line(from_pos=satellites[0].planet.position,
to_pos=satellites[1].planet.position, alpha=0.3)
lines.append(line)
return lines
if __name__ == '__main__': if __name__ == '__main__':
...@@ -114,12 +91,12 @@ if __name__ == '__main__': ...@@ -114,12 +91,12 @@ if __name__ == '__main__':
def on_timer_changed(time_data: TimeData): def on_timer_changed(time_data: TimeData):
# 删除和创建连接线 # 实时删除和创建连接线
from ursina import destroy from ursina import destroy
if hasattr(earth, "lines"): if hasattr(earth, "lines"):
for line in earth.lines: for line in earth.lines:
destroy(line) destroy(line)
# 创建连接线(将卫星列表用线条连接起来)
earth.lines = create_connecting_lines([ earth.lines = create_connecting_lines([
[satelliteL2, satelliteL3], [satelliteL2, satelliteL3],
[satelliteL4, satelliteL1], [satelliteL5, satelliteL1], [satelliteL4, satelliteL1], [satelliteL5, satelliteL1],
...@@ -134,11 +111,13 @@ if __name__ == '__main__': ...@@ -134,11 +111,13 @@ if __name__ == '__main__':
# 运行中,每时每刻都会触发 on_timer_changed # 运行中,每时每刻都会触发 on_timer_changed
UrsinaEvent.on_timer_changed_subscription(on_timer_changed) UrsinaEvent.on_timer_changed_subscription(on_timer_changed)
bodies = [earth, moon,
satelliteL1, satelliteL2, satelliteL3, satelliteL4, satelliteL5]
# 使用 ursina 查看的运行效果 # 使用 ursina 查看的运行效果
# 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹
# position = 左-右+、上+下-、前+后- # position = 左-右+、上+下-、前+后-
ursina_run(bodies, SECONDS_PER_HOUR * 5, ursina_run(bodies, SECONDS_PER_HOUR * 5,
# position=(-300000, 1500000, -100),
position=(0, 1500000, 0), position=(0, 1500000, 0),
show_timer=True, show_timer=True,
# show_trail=True # show_trail=True
......
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*-
# title :拉格朗日点模拟 # title :地月拉格朗日点模拟
# description :拉格朗日点模拟 # description :地月拉格朗日点模拟(对理想的位置进行了调整)
# author :Python超人 # author :Python超人
# date :2023-02-11 # date :2023-05-01
# link :https://gitcode.net/pythoncr/ # link :https://gitcode.net/pythoncr/
# python_version :3.8 # python_version :3.8
# ============================================================================== # ==============================================================================
from bodies import Body, Sun, Earth, Moon from bodies import Earth, Moon
from objs import Obj, Satellite, Satellite2 from objs import Satellite, Satellite2
from common.consts import SECONDS_PER_HOUR, SECONDS_PER_DAY, SECONDS_PER_WEEK, SECONDS_PER_MONTH from common.consts import SECONDS_PER_HOUR, SECONDS_PER_DAY, SECONDS_PER_WEEK, SECONDS_PER_MONTH
from sim_scenes.func import ursina_run, camera_look_at from sim_scenes.func import ursina_run, camera_look_at
from simulators.ursina.entities.body_timer import TimeData from simulators.ursina.entities.body_timer import TimeData
from simulators.ursina.entities.entity_utils import create_directional_light
from simulators.ursina.ursina_event import UrsinaEvent from simulators.ursina.ursina_event import UrsinaEvent
from simulators.ursina.ursina_mesh import create_line from simulators.ursina.ursina_mesh import create_connecting_lines
import math import math
bodies = [ # 月球绕地球的半径
Earth(init_position=[0, 0, 0], texture="earth_hd.jpg", R = 363104
init_velocity=[0, 0, 0], size_scale=0.5e1), # 地球放大 5 倍,距离保持不变 # 创建地月
Moon(init_position=[0, 0, 363104], # 距地距离约: 363104 至 405696 km earth = Earth(init_position=[0, 0, 0], texture="earth_hd.jpg",
init_velocity=[-1.054152222, 0, 0], size_scale=1e1) # 月球放大 10 倍,距离保持不变 init_velocity=[0, 0, 0], size_scale=0.8e1) # 地球放大 8 倍,地月距离保持不变
] moon = Moon(init_position=[0, 0, R], # 距地距离约: 363104 至 405696 km
init_velocity=[-1.054152222, 0, 0], size_scale=1.2e1) # 月球放大 12 倍,地月距离保持不变
earth = bodies[0]
moon = bodies[1]
# 计算地月拉格朗日点
# L1_p, L2_p, L3_p, L4_p, L5_p = get_lagrangian_points(earth.mass, moon.mass, 363104)
# region 在拉格朗日点 L1, L2, L3, L4, L5 (对理想的位置进行了调整)上创建卫星
def create_satellite(name, init_position, init_velocity): def create_satellite(name, init_position, init_velocity):
""" """
在 L1, L2, L3, L4, L5 创建卫星 在 L1, L2, L3, L4, L5 创建卫星
...@@ -38,53 +33,31 @@ def create_satellite(name, init_position, init_velocity): ...@@ -38,53 +33,31 @@ def create_satellite(name, init_position, init_velocity):
@param init_velocity: @param init_velocity:
@return: @return:
""" """
satellite = Satellite(name=name, mass=1.4e10, size_scale=4e3, color=(255, 200, 0), satellite = Satellite(name=name, mass=1.4e10, size_scale=2e3, color=(255, 200, 0),
init_position=init_position, init_position=init_position,
init_velocity=init_velocity, gravity_only_for=[earth, moon]) init_velocity=init_velocity, gravity_only_for=[earth, moon])
return satellite return satellite
# L1:point=[0,0,308536.70059015526] velocity=[-0.890136271716, 0, 0] # 在 L1 位置上创建一个具有初速度的卫星
satelliteL1 = create_satellite(name=f'卫星L1', init_position=[0, 0, 308536.672], satelliteL1 = create_satellite(name=f'卫星L1', init_position=[0, 0, 308536.672],
init_velocity=[-0.890136271716, 0, 0]) init_velocity=[-0.890136271716, 0, 0])
bodies.append(satelliteL1) # 在 L2 位置上创建一个具有初速度的卫星
# L2:point=[0,0, 423338.5083198447] velocity=[-1.24, 0, 0]
satelliteL2 = create_satellite(name=f'卫星L2', init_position=[0, 0, 423338.5083198447], satelliteL2 = create_satellite(name=f'卫星L2', init_position=[0, 0, 423338.5083198447],
init_velocity=[-1.24, 0, 0]) init_velocity=[-1.24, 0, 0])
bodies.append(satelliteL2)
vel_L345 = 1.048 vel_L345 = 1.048
# L3:point=[0,0, -364941.3043941873] velocity=[1.039 , 0, 0] # 在 L3 位置上创建一个具有初速度的卫星
satelliteL3 = create_satellite(name=f'卫星L3', init_position=[0, 0, -364941.3043941873], satelliteL3 = create_satellite(name=f'卫星L3', init_position=[0, 0, -364941.3043941873],
init_velocity=[vel_L345, 0, 0]) init_velocity=[vel_L345, 0, 0])
bodies.append(satelliteL3) # 在 L4 位置上创建一个具有初速度的卫星
# L4:point=[0,0, 177142.46945395062] velocity=[1.039 , 0, 0]
satelliteL4 = create_satellite(name=f'卫星L4', init_position=[314457.2882157448, 0, 177142.46945395062], satelliteL4 = create_satellite(name=f'卫星L4', init_position=[314457.2882157448, 0, 177142.46945395062],
init_velocity=[-math.sin(math.pi * 30 / 180) * vel_L345, 0, init_velocity=[-math.sin(math.pi * 30 / 180) * vel_L345, 0,
math.cos(math.pi * 30 / 180) * vel_L345]) math.cos(math.pi * 30 / 180) * vel_L345])
bodies.append(satelliteL4) # 在 L5 位置上创建一个具有初速度的卫星
# L5:point=[0,0, 177142.46945395062] velocity=[1.039 , 0, 0]
satelliteL5 = create_satellite(name=f'卫星L5', init_position=[-314457.2882157448, 0, 177142.46945395062], satelliteL5 = create_satellite(name=f'卫星L5', init_position=[-314457.2882157448, 0, 177142.46945395062],
init_velocity=[-math.sin(math.pi * 30 / 180) * vel_L345, 0, init_velocity=[-math.sin(math.pi * 30 / 180) * vel_L345, 0,
-math.cos(math.pi * 30 / 180) * vel_L345]) -math.cos(math.pi * 30 / 180) * vel_L345])
bodies.append(satelliteL5) # endregion
def create_connecting_lines(satellites_list):
"""
创建连接线(将卫星列表用线条连接起来)
@param satellites_list:
@return:
"""
lines = []
for satellites in satellites_list:
line = create_line(from_pos=satellites[0].planet.position,
to_pos=satellites[1].planet.position, alpha=0.3)
lines.append(line)
return lines
if __name__ == '__main__': if __name__ == '__main__':
...@@ -95,12 +68,12 @@ if __name__ == '__main__': ...@@ -95,12 +68,12 @@ if __name__ == '__main__':
def on_timer_changed(time_data: TimeData): def on_timer_changed(time_data: TimeData):
# 删除和创建连接线 # 实时删除和创建连接线
from ursina import destroy from ursina import destroy
if hasattr(earth, "lines"): if hasattr(earth, "lines"):
for line in earth.lines: for line in earth.lines:
destroy(line) destroy(line)
# 创建连接线(将卫星列表用线条连接起来)
earth.lines = create_connecting_lines([ earth.lines = create_connecting_lines([
[satelliteL2, satelliteL3], [satelliteL2, satelliteL3],
[satelliteL4, satelliteL1], [satelliteL5, satelliteL1], [satelliteL4, satelliteL1], [satelliteL5, satelliteL1],
...@@ -115,6 +88,8 @@ if __name__ == '__main__': ...@@ -115,6 +88,8 @@ if __name__ == '__main__':
# 运行中,每时每刻都会触发 on_timer_changed # 运行中,每时每刻都会触发 on_timer_changed
UrsinaEvent.on_timer_changed_subscription(on_timer_changed) UrsinaEvent.on_timer_changed_subscription(on_timer_changed)
bodies = [earth, moon,
satelliteL1, satelliteL2, satelliteL3, satelliteL4, satelliteL5]
# 使用 ursina 查看的运行效果 # 使用 ursina 查看的运行效果
# 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹
# position = 左-右+、上+下-、前+后- # position = 左-右+、上+下-、前+后-
......
...@@ -98,7 +98,7 @@ def create_label(parent, label, pos, color, scale=50, alpha=1.0): ...@@ -98,7 +98,7 @@ def create_label(parent, label, pos, color, scale=50, alpha=1.0):
return text return text
def create_line(from_pos, to_pos, parent=None, alpha=1.0, len_scale=1,set_light_off=True, def create_line(from_pos, to_pos, parent=None, alpha=1.0, len_scale=1, set_light_off=True,
color=color.white, thickness=1): color=color.white, thickness=1):
line = Entity(parent=parent, line = Entity(parent=parent,
model=Mesh(vertices=(from_pos * len_scale, to_pos * len_scale), model=Mesh(vertices=(from_pos * len_scale, to_pos * len_scale),
...@@ -154,6 +154,62 @@ def create_arrow_line(from_pos, to_pos, parent=None, label=None, ...@@ -154,6 +154,62 @@ def create_arrow_line(from_pos, to_pos, parent=None, label=None,
return arrow, line, text return arrow, line, text
def get_obj_planet_position(obj):
"""
获取对象的位置坐标
@param obj:
@return:
"""
if hasattr(obj, "planet"):
if hasattr(obj.planet, "main_entity"):
pos1 = obj.planet.main_entity.position
else:
pos1 = obj.planet.position
else:
pos1 = obj.position
return pos1
def create_connecting_line(obj1, obj2, line_color=color.white, alpha=0.3):
"""
创建物体之间的连接线
@param obj1:
@param obj2:
@param line_color: 线条颜色
@param alpha: 透明度(默认0.3)
@return:
"""
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)
pos1 = get_obj_planet_position(obj1)
pos2 = get_obj_planet_position(obj2)
line = create_line(from_pos=pos1, color=line_color, to_pos=pos2, alpha=alpha)
return line
def create_connecting_lines(objs_list, line_color=color.white, alpha=0.3):
"""
创建物体之间的连接线。(多条线)
样例如下: <br>
create_connecting_lines([
[obj1, obj2],
[obj3, obj4],
......
])
@param objs_list:
@param color: 线条颜色
@param alpha: 透明度(默认0.3)
@return: 被创建的连接线列表
"""
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] / 254, alpha)
lines = []
for objs in objs_list:
line = create_connecting_line(objs[0], objs[1], line_color=line_color, alpha=alpha)
lines.append(line)
return lines
def create_pyramid(): def create_pyramid():
# 创建金字塔的顶点 # 创建金字塔的顶点
verts = [ verts = [
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册