“13e0fe0d2a45dc6ee4a963c5b0d7a6077a5a3bc3”上不存在“sim_lab/wormhole_sim_02.py”
提交 2386ae12 编写于 作者: 三月三net's avatar 三月三net

Python超人-宇宙模拟器

上级 8173642d
from objs.obj import Obj
from objs.diamond import Diamond
from objs.football import Football
from objs.satellite import Satellite, Satellite2
......
......@@ -14,6 +14,8 @@ from common.consts import AU
import copy
import os
from simulators.ursina.entities.entity_utils import get_value_direction_vectors
class Obj(metaclass=ABCMeta):
"""
......@@ -197,6 +199,36 @@ class Obj(metaclass=ABCMeta):
self.__position = value
self.__record_history()
def acceleration_value(self):
"""
获取加速度的值(km/s²)
@return:
"""
direction_vectors = get_value_direction_vectors(self.acceleration)
return direction_vectors[0] # km/s²
def velocity_value(self):
"""
获取速度的值(km/s)
@return:
"""
direction_vectors = get_value_direction_vectors(self.velocity)
return direction_vectors[0] # km/s
def acceleration_value_direction(self):
"""
获取加速度的值(km/s²)和方向
@return: 值[0],方向[1]
"""
return get_value_direction_vectors(self.acceleration)
def velocity_value_direction(self):
"""
获取速度的值(km/s)和方向
@return: 值[0],方向[1]
"""
return get_value_direction_vectors(self.velocity)
@property
def acceleration(self):
"""
......
......@@ -7,11 +7,31 @@
# python_version :3.8
# ==============================================================================
from bodies import Body, Sun, Earth, Moon
from objs import Obj
from objs import Satellite, Satellite2
from common.consts import SECONDS_PER_HOUR, SECONDS_PER_DAY, SECONDS_PER_WEEK, SECONDS_PER_MONTH
from sim_scenes.func import calc_run
from bodies.body import AU
from simulators.calc_simulator import CalcSimulator, CalcContext
def get_lagrangian_points(m1, m2, r):
"""
https://baike.baidu.com/item/%E6%8B%89%E6%A0%BC%E6%9C%97%E6%97%A5%E7%82%B9/731078
@param m1: 大质量
@param m2: 小质量
@param r: 半径
@return:
"""
a = m2 / (m1 + m2)
l1 = (0, 0, r * (1 - pow(a / 3, 1 / 3)))
l2 = (0, 0, r * (1 + pow(a / 3, 1 / 3)))
l3 = (0, 0, -r * (1 + (5 * a) / 12))
l4 = (pow(3, 1 / 2) / 2 * r, 0, (r / 2) * ((m1 - m2) / (m1 + m2)))
l5 = (-pow(3, 1 / 2) / 2 * r, 0, (r / 2) * ((m1 - m2) / (m1 + m2)))
return l1, l2, l3, l4, l5
bodies = [
Earth(init_position=[0, 0, 0], texture="earth_hd.jpg",
......@@ -19,17 +39,98 @@ bodies = [
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]
points = get_lagrangian_points(earth.mass, moon.mass, 363104)
L1_point = points[0]
point_z = L1_point[2] + 3301.0505 # 越大,离月球越近
init_velocity = [-0.890211, 0, 0]
satellite = Satellite(name=f'卫星', mass=1.4e10, size_scale=1e3, color=(255, 200, 0),
init_position=[L1_point[0], L1_point[1], point_z],
init_velocity=init_velocity, gravity_only_for=[earth, moon])
bodies.append(satellite)
def calc_simulator():
from simulators.calc_simulator import CalcSimulator, CalcContext
def evolve_next(context: CalcContext):
return context.evolve_count < 500
def after_evolve(dt, context: CalcContext):
target: Body = context.bodies[1]
# target: Obj = context.bodies[2]
context.init_param("acc_values", []).params["acc_values"].append(target.acceleration_value())
context.init_param("vel_values", []).params["vel_values"].append(target.velocity_value())
print(satellite.acceleration_value(), satellite.velocity_value())
def on_finished(context: CalcContext):
import matplotlib.pyplot as plt
# 解决中文显示问题
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
acc_values = context.params["acc_values"]
vel_values = context.params["vel_values"]
max_value = max(acc_values)
min_value = min(acc_values)
fig = plt.figure(figsize=(10, 6))
ax1 = fig.add_subplot(111)
ax1.plot(acc_values, 'blue', label='加速度')
ax1.set_ylabel('加速度', fontdict={'weight': 'normal', 'size': 15, 'color': 'blue'})
# ax1.set_title("加速度/速度", fontdict={'weight': 'normal', 'size': 15})
plt.title("%s max:%.4f mix:%.4f diff:%.4f" % (
moon.init_velocity[0], max_value * 1e6, min_value * 1e6, (max_value - min_value) * 1e6))
l1 = ax1.legend(loc='lower left', labels=['加速度'])
ax2 = ax1.twinx() # this is the important function
ax2.plot(vel_values, 'red', label='速度')
ax2.set_ylabel('速度', fontdict={'weight': 'normal', 'size': 15, 'color': 'red'})
ax2.set_xlabel('Same')
l2 = ax2.legend(loc='upper right', labels=['速度'])
plt.show()
CalcSimulator.on_after_evolve_subscription(after_evolve)
CalcSimulator.on_finished_subscription(on_finished)
calc_run(bodies, SECONDS_PER_HOUR, evolve_next=evolve_next)
def ursina_simulator():
from sim_scenes.func import ursina_run, camera_look_at
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_mesh import create_line
def on_ready():
# 运行前触发
# 运行开始前,将摄像机指向地球
def evolve_next(context: CalcContext):
return context.evolve_count < 200
# 摄像机看向地球
camera_look_at(moon)
def on_timer_changed(time_data: TimeData):
from ursina import destroy
if hasattr(earth, "line"):
destroy(earth.line)
earth.line = create_line(from_pos=earth.planet.position, to_pos=moon.planet.main_entity.position)
def after_evolve(dt, context: CalcContext):
moon: Body = context.bodies[1]
print(moon.acceleration_value(), moon.velocity_value())
# 订阅事件后,上面的函数功能才会起作用
# 运行前会触发 on_ready
UrsinaEvent.on_ready_subscription(on_ready)
# 运行中,每时每刻都会触发 on_timer_changed
UrsinaEvent.on_timer_changed_subscription(on_timer_changed)
# 使用 ursina 查看的运行效果
# 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹
# position = 左-右+、上+下-、前+后-
ursina_run(bodies, SECONDS_PER_HOUR * 10,
position=(-300000, 1500000, -100),
show_timer=True,
show_trail=True)
CalcSimulator.on_after_evolve_subscription(after_evolve)
calc_run(bodies, SECONDS_PER_HOUR, evolve_next=evolve_next)
if __name__ == '__main__':
calc_simulator()
# ursina_simulator()
......@@ -38,6 +38,17 @@ class CalcContext(Singleton):
# 存放参数字典数据,通过 get_param 获取
self._params = {}
def init_param(self, key, value):
"""
只会初始化一次(除非删除掉)
@param key:
@param value:
@return:
"""
if key not in self._params:
self.put_param(key, value)
return self
@property
def bodies(self) -> []:
return self.simulator.bodies_sys.bodies
......@@ -52,6 +63,7 @@ class CalcContext(Singleton):
def put_param(self, key, data):
self._params[key] = data
return self
def get_param(self, key):
"""
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册