diff --git a/sim_scenes/featured/jupiter_moon_protects_earth.py b/sim_scenes/featured/jupiter_moon_protects_earth.py index e1041b6a4fa7a38708986f2cb31faaa7d371f853..3a3a4069dfe904a14c61015d2e032c7b7fecc8f7 100644 --- a/sim_scenes/featured/jupiter_moon_protects_earth.py +++ b/sim_scenes/featured/jupiter_moon_protects_earth.py @@ -6,11 +6,14 @@ # link :https://gitcode.net/pythoncr/ # python_version :3.8 # ============================================================================== +import time + from bodies import Sun, Jupiter, Earth, Moon from common.func import calculate_distance from objs import RockSnow, Rock, create_rock 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.universe_sim_scenes import UniverseSimScenes from simulators.ursina.entities.body_timer import TimeData, BodyTimer from simulators.ursina.entities.entity_utils import create_directional_light from simulators.ursina.ursina_config import UrsinaConfig @@ -20,7 +23,7 @@ import math import numpy as np -class JupiterMoonProtectsEarthSim: +class JupiterMoonProtectsEarthSim(UniverseSimScenes): def __init__(self, comet_num=20): """ @@ -28,11 +31,13 @@ class JupiterMoonProtectsEarthSim: @param comet_num: 随机生成 comet_num 个石头 """ 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.sun = Sun(name="太阳", size_scale=0.8e2) # 太阳放大 80 倍,距离保持不变 - self.jupiter = Jupiter(name="木星", size_scale=0.6e3, distance_scale=0.7) # 木星放大 600 倍,距离保持不变 - self.earth = Earth(name="地球", size_scale=2.5e3) # 地球放大 2000 倍,距离保持不变 + self.sun = Sun(name="太阳", size_scale=0.85e2) # 太阳放大 80 倍,距离保持不变 + self.jupiter = Jupiter(name="木星", size_scale=0.45e3, ignore_mass=True) # 木星放大 600 倍,距离保持不变 + self.earth = Earth(name="地球", size_scale=2.5e3, ignore_mass=True, ) # 地球放大 2000 倍,距离保持不变 self.moon = Moon(name="月球", size_scale=3.5e3, # 月球球放大 3000 倍,为了较好的效果,地月距离要比实际大 init_position=[self.earth_moon_d, 0, AU], init_velocity=[0, 0, 0], @@ -48,16 +53,19 @@ class JupiterMoonProtectsEarthSim: 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): # 随机生成 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.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): sun_pos = self.sun.position @@ -119,8 +127,26 @@ class JupiterMoonProtectsEarthSim: pz = self.earth_moon_d * np.sin(angle) 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): + + 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) + # 运行中,每时每刻都会触发 for comet in self.comets: if comet.planet.enabled: @@ -187,18 +213,31 @@ class JupiterMoonProtectsEarthSim: 0, "0.0%", 0, 0) else: - colliding_info = self.colliding_info % (sun_cnt, str(round(sun_cnt * 100 / total_cnt, 2)) + "%", - jupiter_cnt, str(round(jupiter_cnt * 100 / total_cnt, 2)) + "%", - earth_cnt, str(round(earth_cnt * 100 / total_cnt, 2)) + "%", - moon_cnt, str(round(moon_cnt * 100 / total_cnt, 2)) + "%", + colliding_info = self.colliding_info % (sun_cnt, "%.1f" % (sun_cnt * 100 / total_cnt) + "%", + jupiter_cnt, "%.1f" % (jupiter_cnt * 100 / total_cnt) + "%", + earth_cnt, "%.1f" % (earth_cnt * 100 / total_cnt) + "%", + moon_cnt, "%.1f" % (moon_cnt * 100 / total_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.camera_move(time_data) def camera_move(self, time_data): from ursina import camera - camera.position += camera.left * 0.1 + camera.position += camera.left * 0.01 camera_look_at(self.sun) def on_ready(self): @@ -212,11 +251,11 @@ class JupiterMoonProtectsEarthSim: 0, 0) camera_look_at(self.sun) self.sky = create_sphere_sky(scale=8000) - # self.sky.rotation_y = 100 - # self.sky.rotation_x = 20 + self.sky.rotation_y = -180 + self.sky.rotation_x = -20 # self.sky.rotation_z = -65 application.time_scale = 3 - + self.run_begin_time = time.time() if __name__ == '__main__': @@ -230,7 +269,7 @@ if __name__ == '__main__': # UrsinaConfig.trail_type = "line" UrsinaConfig.trail_length = 30 - sim = JupiterMoonProtectsEarthSim(comet_num=30) + sim = JupiterMoonProtectsEarthSim(comet_num=50) # 运行前会触发 on_ready UrsinaEvent.on_ready_subscription(sim.on_ready) @@ -240,8 +279,11 @@ if __name__ == '__main__': # 使用 ursina 查看的运行效果 # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 # position = 左-右+、上+下-、前+后- - ursina_run(sim.bodies, SECONDS_PER_MONTH * 30, + ursina_run(sim.bodies, SECONDS_PER_MONTH / 6, position=(AU, AU * 5, -AU * 5), cosmic_bg='', show_grid=False, - show_timer=True) + # show_exit_button=False, + show_camera_info=False, + show_control_info=False, + timer_enabled=True)