From 5c5180a4c3d69626ce6f3459701d3649cc5992cd Mon Sep 17 00:00:00 2001 From: march3 Date: Sat, 21 Oct 2023 21:24:25 +0800 Subject: [PATCH] =?UTF-8?q?Python=E8=B6=85=E4=BA=BA-=E5=AE=87=E5=AE=99?= =?UTF-8?q?=E6=A8=A1=E6=8B=9F=E5=99=A8(=E4=BB=A3=E7=A0=81=E5=A4=87?= =?UTF-8?q?=E4=BB=BD=EF=BC=8C=E4=BB=A3=E7=A0=81=E7=9A=84=E6=B8=85=E7=90=86?= =?UTF-8?q?=E6=9C=AA=E5=88=A0=E9=99=A4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/celestial_data_service.py | 16 ++- sim_scenes/tri_bodies/two_way_foil.py | 145 +++++++++----------------- 2 files changed, 60 insertions(+), 101 deletions(-) diff --git a/common/celestial_data_service.py b/common/celestial_data_service.py index 7f671b9..a9a7db0 100644 --- a/common/celestial_data_service.py +++ b/common/celestial_data_service.py @@ -7,10 +7,12 @@ # python_version :3.8 # ============================================================================== import math -from common.consts import G, AU, SECONDS_PER_DAY -from bodies import Body, Sun, Asteroids, Moon, Earth + import numpy as np +from bodies import Body, Sun, Asteroids, Moon, Earth +from common.consts import G, AU, SECONDS_PER_DAY + def calc_solar_acceleration(body_or_pos, big_body): """ @@ -286,9 +288,9 @@ def gen_real_pos_vel_bodies(body_names, dt): pos.y.to(u.km).value, pos.z.to(u.km).value) gen_body_str += f" init_pos_vels['{body_name.lower()}']['vel']=[%.4f,%.4f,%.4f]\n" % ( - vel.x.to(u.km / u.second).value, - vel.y.to(u.km / u.second).value, - vel.z.to(u.km / u.second).value) + vel.x.to(u.km / u.second).value, + vel.y.to(u.km / u.second).value, + vel.z.to(u.km / u.second).value) return gen_body_str # pos, vel = earth_pos_vel[0], earth_pos_vel[1] @@ -302,6 +304,10 @@ def gen_real_pos_vel_bodies(body_names, dt): def get_init_pos_vels(): + """ + 获取初始位置和速度(方便模拟) + @return: + """ init_pos_vels = {} init_pos_vels['sun'] = {} init_pos_vels['sun']['pos'] = [-4638653.0000, 0.0000, 1314332.6250] diff --git a/sim_scenes/tri_bodies/two_way_foil.py b/sim_scenes/tri_bodies/two_way_foil.py index 9e7295f..138e4cf 100644 --- a/sim_scenes/tri_bodies/two_way_foil.py +++ b/sim_scenes/tri_bodies/two_way_foil.py @@ -16,7 +16,6 @@ from common.consts import SECONDS_PER_WEEK, AU from objs import QuadObj, CircleObj, Obj from sim_scenes.func import camera_look_at, two_bodies_colliding from sim_scenes.func import ursina_run, create_sphere_sky -from simulators.ursina.entities.entity_utils import create_rings from simulators.ursina.ursina_event import UrsinaEvent @@ -26,9 +25,6 @@ class TwoWayFoilSim: """ def __init__(self): - - # self.three_dim_bodies = [] - # self.two_dim_bodies = [] self.current_stage = self.stage_01 def build_solar_system(self): @@ -48,6 +44,7 @@ class TwoWayFoilSim: ] # endregion + # 获取模拟的初始位置和速度 init_pos_vels = get_init_pos_vels() for body in self.bodies: @@ -58,13 +55,18 @@ class TwoWayFoilSim: body.init_velocity = pos_vels['vel'] def build_two_way_foil(self): + """ + 创建二向箔(一个原始的方形二向箔,一个不断扩展的圆形二向箔) + @return: + """ + # 原始的方形二向箔 self.two_way_foil = QuadObj(texture='two_way_foil.png', # size_scale=4e7, size_scale=1e7, init_velocity=[0, -6, 150], init_position=[0, 0.5 * AU, -10 * AU]) \ .set_light_disable(True).set_ignore_gravity(True) - + # 不断扩展的圆形二向箔 self.two_way_foil_circle = CircleObj(texture="two_way_foil_circle.png", size_scale=self.two_way_foil.size_scale * 2, ) \ @@ -73,33 +75,9 @@ class TwoWayFoilSim: self.bodies.append(self.two_way_foil) self.bodies.append(self.two_way_foil_circle) - # def create_two_dim(self, body): - # body_2dim = CircleObj(texture=body.texture, - # size_scale=body.diameter * body.size_scale, - # distance_scale=body.distance_scale, - # init_position=body.position) \ - # .set_light_disable(True).set_ignore_gravity(True) - # - # body.two_dim = body_2dim - # body_2dim.three_dim = body - # return body_2dim - - # def build_two_dim_bodies(self): - # for body in self.bodies: - # # two_dim_body = self.create_two_dim(body) - # self.three_dim_bodies.append(body) - # # self.two_dim_bodies.append(two_dim_body) - # - # self.bodies.append(self.two_way_foil) - # self.bodies.append(self.two_way_foil_circle) - # - # for body in self.two_dim_bodies: - # self.bodies.append(body) - def build(self): self.build_solar_system() self.build_two_way_foil() - # self.build_two_dim_bodies() def on_ready(self): """ @@ -111,129 +89,104 @@ class TwoWayFoilSim: camera.clip_plane_far = 1000000 create_sphere_sky(scale=200000) application.time_scale = 5 - # for body in self.two_dim_bodies: - # body.planet.enabled = False - # model = body.planet.model - # if body.three_dim.has_rings: - # rings = create_rings(body.planet) - # rings.scale *= 2e10 - + # 圆形二向箔初始化(一开始不显示) self.two_way_foil_circle.planet.rotation_x = 90 self.two_way_foil_circle.planet.enabled = False - # self.two_way_foil.planet.alpha = 0.6 - - # for b in self.two_dim_bodies: - # b.planet.rotation_x = 90 def flatten_animation(self, body): + """ + 天体二维化的动画 + @param body: 天体 + @return: + """ + def flatten_update(planet): def warp(): + # 原始的 update 方法中有计算天体的运行 planet.init_update() - # time.sleep(0.2) + + # 对Y轴进行压平动画,如果压平大小不足 1/20,则继续压缩,直到压缩到 1/20 就不压缩了 + # (如果觉得 1/20 的厚度压的不够,还可以继续压缩,基本上就够了) if planet.scale_y > planet.init_scale_y / 20: planet.scale_y_v /= 1.01 - # planet.enabled = False - # flatten_planet.enabled = True - # planet.update = planet.init_update - # elif planet.scale_y < planet.init_scale_y / 1.01: - # planet.set_light_off(True) + # 灯光关闭,不然压到2纬就会是黑色 planet.set_light_off(True) planet.scale_y = planet.scale_y_v return warp + # 压平时,转速将为以前的 1/20 body.planet.rotation_speed /= 20 + # 记录原始的厚度大小 body.planet.scale_y_v = body.planet.scale_y body.planet.init_scale_y = body.planet.scale_y + # 原始的 update 方法中有计算天体的运行,需要保留 body.planet.init_update = body.planet.update + # 替换 update body.planet.update = flatten_update(body.planet) - # for i in range(10): - # # body.planet.scale_y /= 2 - # body.init_scale = [body.init_scale[0], body.init_scale[1] / 2, body.init_scale[2]] - # time.sleep(0.2) - # body.planet.enabled = False - # flatten_body.planet.enabled = True - # flatten_body.planet.x += 100000 - def stage_01(self): """ 二向箔飞向太阳 @return: """ + + # 如果二向箔和太阳碰撞 if two_bodies_colliding(self.two_way_foil, self.sun): - # t = threading.Thread(target=self.flatten_animation, args=[self.sun, self.sun.two_dim]) - # t.start() - # for i in range(10): - # self.sun.planet.scale_y /= 0.5 - # time.sleep(1) - # self.sun.planet.enabled = False - # self.sun.two_dim.planet.enabled = True - # self.sun.two_dim.planet.x += 100000 - # two_way_foil.explode(sun) + # 隐藏原始二向箔,保持在原地,不在飞行 self.two_way_foil.planet.enabled = False + self.two_way_foil.init_velocity = [0, 0, 0] + # 圆形二向箔显示并设置透明度为0.9 self.two_way_foil_circle.planet.alpha = 0.9 self.two_way_foil_circle.planet.enabled = True + # 当前阶段为 stage_02:二向箔压平天体的阶段 self.current_stage = self.stage_02 - def blink(self, body): - return - if not hasattr(body, "blink_d"): - body.blink_d = 1 - body.blink_v = 1 - - if body.blink_d > 0: - body.blink_v -= 0.05 - body.planet.alpha = body.blink_v - if body.blink_v <= 0.7: - body.blink_d = -1 - elif body.blink_d < 0: - body.blink_v += 0.05 - body.planet.alpha = body.blink_v - if body.blink_v >= 1: - body.blink_d = 1 - def stage_02(self): """ - + 二向箔压平天体(二维化)的阶段 @return: """ # self.sun.two_dim.planet.init_scale += 0.05 + # 圆形二向箔不断扩展变大 self.two_way_foil_circle.planet.init_scale += 0.8 - # self.blink(self.sun.two_dim) - # 二维化延时的时间 + # 调整天体二维化的时间,一般需要延时,保证扩展和二维化同步的真实效果 two_way_delay_times = [0.5, # 太阳 0.5, 0.8, 1.0, # 水星 金星 地球 1.2, 2.0, 3.0, # 火星 木星 土星 4.0, 4.5, 5.5] # 天王星 海王星 冥王星 for idx, b in enumerate(self.bodies): if isinstance(b, Obj): + # 二向箔不处理 continue if hasattr(b, "two_way_time"): + # 二向箔和天体碰撞的时间不为空,则说明已经碰撞 if b.two_way_time is not None: + # 如果碰撞后的延时时间到,则进行压平天体处理(二维化) if time.time() - b.two_way_time > two_way_delay_times[idx]: self.flatten_animation(b) - # b.planet.enabled = False - # b.two_dim.planet.enabled = True + # 二向箔和天体碰撞的时间设置为空,就是说明二维化结束 b.two_way_time = None elif two_bodies_colliding(self.two_way_foil_circle, b): + # 二向箔和天体碰撞,但暂时先不二维化,记下时间,延时二维化 b.two_way_time = time.time() - # b.planet.enabled = False - # b.two_dim.planet.enabled = True - # if b.two_dim.planet.enabled: - # # b.two_dim.planet.init_scale += 0.05 - # self.blink(b.two_dim) + + # 圆形二向箔不断旋转的效果 self.two_way_foil_circle.planet.rotation_z += 0.4 def on_timer_changed(self, time_data): - self.two_way_foil.planet.rotation_x += 0.1 - self.two_way_foil.planet.rotation_y += 1 - # self.two_way_foil.planet.rotation_z += 10 + """ + + @param time_data: + @return: + """ + # 原始方形二向箔飞行的翻转效果 + if self.two_way_foil.planet.enabled: + self.two_way_foil.planet.rotation_x += 0.1 + self.two_way_foil.planet.rotation_y += 1 + # 摄像机始终看向二向箔 camera_look_at(self.two_way_foil) self.current_stage() - # for b in self.two_dim_bodies: - # b.planet.rotation_y -= 0.5 - # b.init_position = b.three_dim.position if __name__ == '__main__': -- GitLab