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

Python超人-宇宙模拟器

上级 70bcc5dc
...@@ -6,11 +6,14 @@ ...@@ -6,11 +6,14 @@
# link :https://gitcode.net/pythoncr/ # link :https://gitcode.net/pythoncr/
# python_version :3.8 # python_version :3.8
# ============================================================================== # ==============================================================================
import time
from bodies import Sun, Jupiter, Earth, Moon from bodies import Sun, Jupiter, Earth, Moon
from common.func import calculate_distance from common.func import calculate_distance
from objs import RockSnow, Rock, create_rock from objs import RockSnow, Rock, create_rock
from common.consts import SECONDS_PER_MONTH, SECONDS_PER_YEAR, AU from common.consts import SECONDS_PER_MONTH, SECONDS_PER_YEAR, AU
from sim_scenes.func import ursina_run, camera_look_at, two_bodies_colliding, create_text_panel, create_sphere_sky from sim_scenes.func import ursina_run, camera_look_at, two_bodies_colliding, create_text_panel, create_sphere_sky
from sim_scenes.universe_sim_scenes import UniverseSimScenes
from simulators.ursina.entities.body_timer import TimeData, BodyTimer from simulators.ursina.entities.body_timer import TimeData, BodyTimer
from simulators.ursina.entities.entity_utils import create_directional_light from simulators.ursina.entities.entity_utils import create_directional_light
from simulators.ursina.ursina_config import UrsinaConfig from simulators.ursina.ursina_config import UrsinaConfig
...@@ -20,7 +23,7 @@ import math ...@@ -20,7 +23,7 @@ import math
import numpy as np import numpy as np
class JupiterMoonProtectsEarthSim: class JupiterMoonProtectsEarthSim(UniverseSimScenes):
def __init__(self, comet_num=20): def __init__(self, comet_num=20):
""" """
...@@ -28,11 +31,13 @@ class JupiterMoonProtectsEarthSim: ...@@ -28,11 +31,13 @@ class JupiterMoonProtectsEarthSim:
@param comet_num: 随机生成 comet_num 个石头 @param comet_num: 随机生成 comet_num 个石头
""" """
self.earth_moon_d = 30000000 # 因为地球放大 2000 倍,为了较好的效果,地月距离要比实际大才行 self.earth_moon_d = 30000000 # 因为地球放大 2000 倍,为了较好的效果,地月距离要比实际大才行
self.sun_earth_d = 150000000
self.sun_jupiter_d = 320000000
# 分别保存太阳碰撞次数、木星碰撞次数、地球碰撞次数、月球碰撞次数、木星保护次数、月球保护次数 # 分别保存太阳碰撞次数、木星碰撞次数、地球碰撞次数、月球碰撞次数、木星保护次数、月球保护次数
self.colliding_count = [0, 0, 0, 0, 0, 0] self.colliding_count = [0, 0, 0, 0, 0, 0]
self.sun = Sun(name="太阳", size_scale=0.8e2) # 太阳放大 80 倍,距离保持不变 self.sun = Sun(name="太阳", size_scale=0.85e2) # 太阳放大 80 倍,距离保持不变
self.jupiter = Jupiter(name="木星", size_scale=0.6e3, distance_scale=0.7) # 木星放大 600 倍,距离保持不变 self.jupiter = Jupiter(name="木星", size_scale=0.45e3, ignore_mass=True) # 木星放大 600 倍,距离保持不变
self.earth = Earth(name="地球", size_scale=2.5e3) # 地球放大 2000 倍,距离保持不变 self.earth = Earth(name="地球", size_scale=2.5e3, ignore_mass=True, ) # 地球放大 2000 倍,距离保持不变
self.moon = Moon(name="月球", size_scale=3.5e3, # 月球球放大 3000 倍,为了较好的效果,地月距离要比实际大 self.moon = Moon(name="月球", size_scale=3.5e3, # 月球球放大 3000 倍,为了较好的效果,地月距离要比实际大
init_position=[self.earth_moon_d, 0, AU], init_position=[self.earth_moon_d, 0, AU],
init_velocity=[0, 0, 0], init_velocity=[0, 0, 0],
...@@ -48,16 +53,19 @@ class JupiterMoonProtectsEarthSim: ...@@ -48,16 +53,19 @@ class JupiterMoonProtectsEarthSim:
self.comets = [] self.comets = []
self.comet_radius = calculate_distance(self.jupiter.position, self.sun.position) * 1.5 self.comet_radius = self.sun_jupiter_d * 1.5
# calculate_distance(self.jupiter.position, self.sun.position) # * 1.5
for i in range(comet_num): for i in range(comet_num):
# 随机生成 comet_num 个石头 # 随机生成 comet_num 个石头
comet = self.create_comet(i, gravity_only_for=[self.sun, self.jupiter, self.earth]) comet = self.create_comet(i, gravity_only_for=[self.sun])
# comet = self.create_comet(i, gravity_only_for=[self.sun, self.jupiter, self.earth])
self.bodies.append(comet) self.bodies.append(comet)
self.comets.append(comet) self.comets.append(comet)
# 显示板信息模板 # 显示板信息模板
self.colliding_info = "太阳碰撞:%s次(%s)\n\n木星碰撞:%s次(%s)\n\n地球碰撞:%s次(%s)\n\n月球碰撞:%s次(%s)\n\n木星保护:%s次\n\n月球保护:%s次\n\n" self.colliding_info = "陨石碰撞(次数)\n\n - 太阳: %s次(%s)\n\n - 木星: %s次(%s)\n\n - 地球: %s次(%s)\n\n - 月球: %s次(%s)" \
"\n\n保护地球(次数)\n\n - 木星: %s次\n\n - 月球: %s次\n\n"
def random_pos_vel(self): def random_pos_vel(self):
sun_pos = self.sun.position sun_pos = self.sun.position
...@@ -119,8 +127,26 @@ class JupiterMoonProtectsEarthSim: ...@@ -119,8 +127,26 @@ class JupiterMoonProtectsEarthSim:
pz = self.earth_moon_d * np.sin(angle) pz = self.earth_moon_d * np.sin(angle)
self.moon.position = [self.earth.position[0] + px, 0, self.earth.position[2] + pz] self.moon.position = [self.earth.position[0] + px, 0, self.earth.position[2] + pz]
def set_planet_position(self, planet, time_data, month_per_year, d):
# 1个月有29.5天
days_per_month = 29.5 * month_per_year
# 1天多少角度
angle_per_day = 360 / days_per_month
# 当前天数的角度(度)
angle = time_data.total_days * angle_per_day
# 当前天数的角度(弧度)
angle = angle * np.pi / 180
# 计算月亮的坐标(这里没有用到万有引力)
px = d * np.cos(angle)
pz = d * np.sin(angle)
planet.position = [self.sun.position[0] + px, 0, self.sun.position[2] + pz]
def on_timer_changed(self, time_data: TimeData): def on_timer_changed(self, time_data: TimeData):
self.set_planet_position(self.earth, time_data, 12, self.sun_earth_d)
self.set_planet_position(self.jupiter, time_data, 12 * 11.8622, self.sun_jupiter_d)
self.set_moon_position(time_data) self.set_moon_position(time_data)
# 运行中,每时每刻都会触发 # 运行中,每时每刻都会触发
for comet in self.comets: for comet in self.comets:
if comet.planet.enabled: if comet.planet.enabled:
...@@ -187,18 +213,31 @@ class JupiterMoonProtectsEarthSim: ...@@ -187,18 +213,31 @@ class JupiterMoonProtectsEarthSim:
0, "0.0%", 0, "0.0%",
0, 0) 0, 0)
else: else:
colliding_info = self.colliding_info % (sun_cnt, str(round(sun_cnt * 100 / total_cnt, 2)) + "%", colliding_info = self.colliding_info % (sun_cnt, "%.1f" % (sun_cnt * 100 / total_cnt) + "%",
jupiter_cnt, str(round(jupiter_cnt * 100 / total_cnt, 2)) + "%", jupiter_cnt, "%.1f" % (jupiter_cnt * 100 / total_cnt) + "%",
earth_cnt, str(round(earth_cnt * 100 / total_cnt, 2)) + "%", earth_cnt, "%.1f" % (earth_cnt * 100 / total_cnt) + "%",
moon_cnt, str(round(moon_cnt * 100 / total_cnt, 2)) + "%", moon_cnt, "%.1f" % (moon_cnt * 100 / total_cnt) + "%",
j_protected_cnt, m_protected_cnt) j_protected_cnt, m_protected_cnt)
ctime = time.time()
if m_protected_cnt >= 8 and j_protected_cnt >= 2:
if not hasattr(self, "m_protected_8_time"):
self.m_protected_8_time = ctime
else:
if ctime - self.m_protected_8_time > 30:
print("满足条件退出")
exit()
if ctime - self.run_begin_time > 600:
print("没有满足条件退出")
exit()
self.text_panel.text = colliding_info self.text_panel.text = colliding_info
self.camera_move(time_data) self.camera_move(time_data)
def camera_move(self, time_data): def camera_move(self, time_data):
from ursina import camera from ursina import camera
camera.position += camera.left * 0.1 camera.position += camera.left * 0.01
camera_look_at(self.sun) camera_look_at(self.sun)
def on_ready(self): def on_ready(self):
...@@ -212,11 +251,11 @@ class JupiterMoonProtectsEarthSim: ...@@ -212,11 +251,11 @@ class JupiterMoonProtectsEarthSim:
0, 0) 0, 0)
camera_look_at(self.sun) camera_look_at(self.sun)
self.sky = create_sphere_sky(scale=8000) self.sky = create_sphere_sky(scale=8000)
# self.sky.rotation_y = 100 self.sky.rotation_y = -180
# self.sky.rotation_x = 20 self.sky.rotation_x = -20
# self.sky.rotation_z = -65 # self.sky.rotation_z = -65
application.time_scale = 3 application.time_scale = 3
self.run_begin_time = time.time()
if __name__ == '__main__': if __name__ == '__main__':
...@@ -230,7 +269,7 @@ if __name__ == '__main__': ...@@ -230,7 +269,7 @@ if __name__ == '__main__':
# UrsinaConfig.trail_type = "line" # UrsinaConfig.trail_type = "line"
UrsinaConfig.trail_length = 30 UrsinaConfig.trail_length = 30
sim = JupiterMoonProtectsEarthSim(comet_num=30) sim = JupiterMoonProtectsEarthSim(comet_num=50)
# 运行前会触发 on_ready # 运行前会触发 on_ready
UrsinaEvent.on_ready_subscription(sim.on_ready) UrsinaEvent.on_ready_subscription(sim.on_ready)
...@@ -240,8 +279,11 @@ if __name__ == '__main__': ...@@ -240,8 +279,11 @@ if __name__ == '__main__':
# 使用 ursina 查看的运行效果 # 使用 ursina 查看的运行效果
# 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹
# position = 左-右+、上+下-、前+后- # position = 左-右+、上+下-、前+后-
ursina_run(sim.bodies, SECONDS_PER_MONTH * 30, ursina_run(sim.bodies, SECONDS_PER_MONTH / 6,
position=(AU, AU * 5, -AU * 5), position=(AU, AU * 5, -AU * 5),
cosmic_bg='', cosmic_bg='',
show_grid=False, show_grid=False,
show_timer=True) # show_exit_button=False,
show_camera_info=False,
show_control_info=False,
timer_enabled=True)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册