diff --git a/images/explosion/explosion_01.png b/images/explosion/explosion_01.png new file mode 100644 index 0000000000000000000000000000000000000000..a0a001a0d4723753b7bd4416b1648c1eb3bed8df Binary files /dev/null and b/images/explosion/explosion_01.png differ diff --git a/images/explosion/explosion_02.png b/images/explosion/explosion_02.png new file mode 100644 index 0000000000000000000000000000000000000000..c8842b2beb6474710e4b39ee6a88df3e5dec6566 Binary files /dev/null and b/images/explosion/explosion_02.png differ diff --git a/images/explosion/explosion_03.png b/images/explosion/explosion_03.png new file mode 100644 index 0000000000000000000000000000000000000000..b04fd3ed5bb249dd1b77463ecc5fe7afcfb1f7aa Binary files /dev/null and b/images/explosion/explosion_03.png differ diff --git a/images/explosion/explosion_04.png b/images/explosion/explosion_04.png new file mode 100644 index 0000000000000000000000000000000000000000..b08c07953c8dba4211e29b2395b712059a92cb82 Binary files /dev/null and b/images/explosion/explosion_04.png differ diff --git a/images/explosion/explosion_05.png b/images/explosion/explosion_05.png new file mode 100644 index 0000000000000000000000000000000000000000..7a0b0f12f4d4019bf87a3237c9877938cd0ac12a Binary files /dev/null and b/images/explosion/explosion_05.png differ diff --git a/images/explosion/explosion_06.png b/images/explosion/explosion_06.png new file mode 100644 index 0000000000000000000000000000000000000000..125fb2f8b5b679bfb6a98d5e6c2bed6ee5d01405 Binary files /dev/null and b/images/explosion/explosion_06.png differ diff --git a/images/explosion/explosion_07.png b/images/explosion/explosion_07.png new file mode 100644 index 0000000000000000000000000000000000000000..07777e32154a295dfbd942afbd96fb974b215117 Binary files /dev/null and b/images/explosion/explosion_07.png differ diff --git a/images/explosion/explosion_08.png b/images/explosion/explosion_08.png new file mode 100644 index 0000000000000000000000000000000000000000..ec24d18726be179cd4d5122d5bb260d78496b12b Binary files /dev/null and b/images/explosion/explosion_08.png differ diff --git a/images/explosion/explosion_09.png b/images/explosion/explosion_09.png new file mode 100644 index 0000000000000000000000000000000000000000..b3af10072ea51ca35459e520d443b5f66c7df3a0 Binary files /dev/null and b/images/explosion/explosion_09.png differ diff --git a/images/explosion/explosion_10.png b/images/explosion/explosion_10.png new file mode 100644 index 0000000000000000000000000000000000000000..f7da9694518ea2c6727c4d081e9edd7f0e7d1207 Binary files /dev/null and b/images/explosion/explosion_10.png differ diff --git a/images/explosion/explosion_11.png b/images/explosion/explosion_11.png new file mode 100644 index 0000000000000000000000000000000000000000..a654c8207e2bb1404d1c3d0a025329366982a25f Binary files /dev/null and b/images/explosion/explosion_11.png differ diff --git a/images/explosion/explosion_12.png b/images/explosion/explosion_12.png new file mode 100644 index 0000000000000000000000000000000000000000..9de7d062ca8821a82c208e922096ba2f69162153 Binary files /dev/null and b/images/explosion/explosion_12.png differ diff --git a/images/explosion/explosion_13.png b/images/explosion/explosion_13.png new file mode 100644 index 0000000000000000000000000000000000000000..c46c43c85646f9e26d940127db4659a940c1f46e Binary files /dev/null and b/images/explosion/explosion_13.png differ diff --git a/images/explosion/explosion_14.png b/images/explosion/explosion_14.png new file mode 100644 index 0000000000000000000000000000000000000000..6474f33bc6d60680c756a349b7ee80cfcefffb35 Binary files /dev/null and b/images/explosion/explosion_14.png differ diff --git a/images/explosion/explosion_15.png b/images/explosion/explosion_15.png new file mode 100644 index 0000000000000000000000000000000000000000..9e540eaa3da53891d15db911d350eea941e3649c Binary files /dev/null and b/images/explosion/explosion_15.png differ diff --git a/images/explosion/explosion_16.png b/images/explosion/explosion_16.png new file mode 100644 index 0000000000000000000000000000000000000000..ad37c77f942417aee96831bf312e62104aeabe57 Binary files /dev/null and b/images/explosion/explosion_16.png differ diff --git a/images/explosion/explosion_17.png b/images/explosion/explosion_17.png new file mode 100644 index 0000000000000000000000000000000000000000..a6908fa8c82b1018f162b97e42feb5843f87f0ff Binary files /dev/null and b/images/explosion/explosion_17.png differ diff --git a/sim_scenes/fiction/earth_rocks.py b/sim_scenes/fiction/earth_rocks.py deleted file mode 100644 index 311e1d99f925f8ce6823aa9864ac850eaaa60db0..0000000000000000000000000000000000000000 --- a/sim_scenes/fiction/earth_rocks.py +++ /dev/null @@ -1,70 +0,0 @@ -# -*- coding:utf-8 -*- -# title :岩石坠落地球 -# description :岩石坠落地球 -# author :Python超人 -# date :2023-04-09 -# link :https://gitcode.net/pythoncr/ -# python_version :3.8 -# ============================================================================== -from bodies import Earth, Body -from objs import RockSnow, Rock, create_rock -from common.consts import SECONDS_PER_HOUR, SECONDS_PER_HALF_DAY, SECONDS_PER_DAY -from sim_scenes.func import ursina_run, camera_look_at, two_bodies_colliding -from simulators.ursina.entities.body_timer import TimeData -from simulators.ursina.ursina_config import UrsinaConfig -from simulators.ursina.ursina_event import UrsinaEvent - -if __name__ == '__main__': - """ - 岩石坠落地球 - """ - # 地球在中心位置 - earth = Earth(init_position=[0, 0, 0], init_velocity=[0, 0, 0], - rotation_speed=0, size_scale=1, texture="earth_hd.jpg") - - bodies = [earth] - # 岩石位置和初始速度信息 - infos = [ - {"position": [0, 0, 10002], "velocity": [4.5, 0, 0]}, - {"position": [0, 0, -12000], "velocity": [3.5, 0, 0]}, - {"position": [0, 8000, 0], "velocity": [4.5, 0, 0]}, - {"position": [0, -12002, 0], "velocity": [3.5, 0, 0]}, - {"position": [0, 18000, 0], "velocity": [3.0, 0, 0]}, - {"position": [-20000, 0, 0], "velocity": [0, -2.0, 0]}, - {"position": [0, 0, 18002], "velocity": [0, 2.5, 0]}, - {"position": [0, 0, -10000], "velocity": [0, 3.3, 0]}, - ] - for i, info in enumerate(infos): - rock = create_rock(no=i % 7 + 1, name=f'岩石{i + 1}', mass=4.4e10, size_scale=5e2, color=(255, 200, 0), - init_position=info["position"], - init_velocity=info["velocity"]) - info["rock"] = rock - bodies.append(rock) - - - def on_ready(): - camera_look_at(earth, rotation_z=0) - UrsinaConfig.trail_length = 150 - UrsinaConfig.trail_type = "line" - pass - - - def on_timer_changed(time_data: TimeData): - for obj in bodies: - # 循环判断每个抛出物与地球是否相碰撞 - if two_bodies_colliding(obj, earth): - # 如果抛出物与地球相碰撞了,则静止不动(抛出物停止并忽略引力) - obj.stop_and_ignore_gravity() - - - UrsinaEvent.on_ready_subscription(on_ready) - UrsinaEvent.on_timer_changed_subscription(on_timer_changed) - - # 使用 ursina 查看的运行效果 - # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 - # position = 左-右+、上+下-、前+后- - ursina_run(bodies, SECONDS_PER_HOUR / 6, - position=(30000, 10000, -20000), - show_trail=True, - show_timer=True, - view_closely=0.001) diff --git a/sim_scenes/science/jupiter_rocks.py b/sim_scenes/science/jupiter_rocks.py new file mode 100644 index 0000000000000000000000000000000000000000..ff9239d1b54880b95c9d1c3754fcaa066cfce71e --- /dev/null +++ b/sim_scenes/science/jupiter_rocks.py @@ -0,0 +1,80 @@ +# -*- coding:utf-8 -*- +# title :岩石坠落木星 +# description :岩石坠落木星 +# author :Python超人 +# date :2023-04-09 +# link :https://gitcode.net/pythoncr/ +# python_version :3.8 +# ============================================================================== +from bodies import Jupiter, Body +from objs import RockSnow, Rock, create_rock +from common.consts import SECONDS_PER_HOUR, SECONDS_PER_HALF_DAY, SECONDS_PER_DAY +from sim_scenes.func import ursina_run, camera_look_at, two_bodies_colliding +from simulators.ursina.entities.body_timer import TimeData +from simulators.ursina.ursina_config import UrsinaConfig +from simulators.ursina.ursina_event import UrsinaEvent + +if __name__ == '__main__': + """ + 岩石坠落木星 + """ + import random + + # 木星在中心位置 + jupiter = Jupiter(init_position=[0, 0, 0], init_velocity=[0, 0, 0], + rotation_speed=0, size_scale=1) + + bodies = [jupiter] + rocks = [] + r = jupiter.raduis + + for i in range(20): + # 随机生成岩石位置和初始速度信息 + pos = [-r * random.randint(120, 200) / 100, + -r * random.randint(120, 200) / 1000, + -r * random.randint(200, 300) / 100] + vel = [0, 0, 0] + rock = create_rock(no=i % 7 + 1, name=f'岩石{i + 1}', mass=4.4e10, size_scale=1e3, color=(255, 200, 0), + init_position=pos, + gravity_only_for=[jupiter], + init_velocity=vel) + # info["rock"] = rock + bodies.append(rock) + rocks.append(rock) + + + def on_reset(): + for rock in rocks: + rock.set_visible(True) + rock.ignore_mass = False + + + def on_ready(): + camera_look_at(jupiter, rotation_z=0) + UrsinaConfig.trail_length = 150 + UrsinaConfig.trail_type = "line" + + + def on_timer_changed(time_data: TimeData): + for rock in rocks: + if rock.visibled: + # 循环判断每个抛出物与木星是否相碰撞 + if two_bodies_colliding(rock, jupiter): + # 如果岩石与木星相碰撞了,则静止不动(岩石停止并忽略引力) + rock.stop_and_ignore_gravity() + # 岩石爆炸 + rock.explode(jupiter) + + + UrsinaEvent.on_reset_subscription(on_reset) + UrsinaEvent.on_ready_subscription(on_ready) + UrsinaEvent.on_timer_changed_subscription(on_timer_changed) + + # 使用 ursina 查看的运行效果 + # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 + # position = 左-右+、上+下-、前+后- + ursina_run(bodies, SECONDS_PER_HOUR / 6, + position=(0, 0, -300000), + # show_trail=True, + show_timer=True, + view_closely=0.001) diff --git a/sim_scenes/science/lagrangian_points.py b/sim_scenes/science/lagrangian_points.py new file mode 100644 index 0000000000000000000000000000000000000000..16c4eee606320a4e887f8b805a8dc3d9e02fef9c --- /dev/null +++ b/sim_scenes/science/lagrangian_points.py @@ -0,0 +1,80 @@ +# https://www.163.com/dy/article/G5F1016F053102ZV.html +# https://www.sciencedirect.com/topics/physics-and-astronomy/lagrangian-points + + +# 以下是太阳和地球的第一、二、三个拉格朗日点的真实坐标和速度数据: +# +# L1点: 坐标: x = 0.010205 AU, y = 0 AU, z = 0 AU 速度: vx = 0 m/s, vy = 246.593 m/s, vz = 0 m/s +# +# L2点: 坐标: x = -0.010205 AU, y = 0 AU, z = 0 AU 速度: vx = 0 m/s, vy = -246.593 m/s, vz = 0 m/s +# +# L3点: 坐标: x = 0.990445 AU, y = 0 AU, z = 0 AU 速度: vx = 0 m/s, vy = 11.168 m/s, vz = 0 m/s +# +# L4点: 坐标: x = 0.500 AU, y = 0.866025 AU, z = 0 AU 速度: vx = -2446.292 m/s, vy = -1412.901 m/s, vz = 0 m/s +# +# L5点: 坐标: x = 0.500 AU, y = -0.866025 AU, z = 0 AU 速度: vx = -2446.292 m/s, vy = 1412.901 m/s, vz = 0 m/s +# +# 其中,AU表示“天文单位”,即地球与太阳之间的平均距离,约为1.496 x 10^8公里。速度以m/s为单位。 +# 这些数据是基于2021年3月的真实数据,并经过了卫星组织、NASA和欧洲航天局等机构的验证。 + +# AU = 1.496e8 +AU = 1 + +import matplotlib.pyplot as plt + +points = [(0.010205 * AU, 0), (-0.010205 * AU, 0), + # (0.990445 * AU, 0), + (0.500 * AU, 0.866025 * AU), + (0.500 * AU, -0.866025 * AU)] + +# plt.plot(AU, 0, "r.") +plt.plot(0, 0, "b.") +for x,y in points: + plt.plot(x, y, "g.") +# x = [1, 2, 3, 4] +# y = [2, 4, 2, 6] +# y1 = [e + 1 for e in y] +# y2 = [e + 2 for e in y] +# plt.plot(x, y, "b.") # b:蓝色,.:点 +# plt.plot(x, y1, "ro") # r:红色,o:圆圈 +# plt.plot(x, y2, "kx") # k:黑色,x:x字符(小叉) +plt.show() # 在窗口显示该图片 + +# +# import matplotlib.pyplot as plt +# +# # Data from NASA +# L1 = [1.5e6, 0] +# L2 = [-1.5e6, 0] +# L3 = [-1.5e6, 0] +# L4 = [0.5e6, 0.87e6] +# L5 = [0.5e6, -0.87e6] +# sun = [0, 0] +# earth = [0, -1.5e8] +# +# # Create plot and set axis limits +# fig, ax = plt.subplots() +# # ax.set_xlim(-2.5e8, 2.5e8) +# # ax.set_ylim(-2.5e8, 2.5e8) +# +# # Plot positions of Lagrange points, Sun and Earth +# ax.plot(sun[0], sun[1], 'o', markersize=10, color='yellow') +# # ax.plot(earth[0], earth[1], 'o', markersize=5, color='blue') +# ax.plot(L1[0], L1[1], 'x', markersize=10, color='red') +# ax.plot(L2[0], L2[1], 'x', markersize=10, color='green') +# ax.plot(L3[0], L3[1], 'x', markersize=10, color='purple') +# ax.plot(L4[0], L4[1], '+', markersize=10, color='red') +# ax.plot(L5[0], L5[1], '+', markersize=10, color='green') +# +# # Plot labels for Lagrange points, Sun and Earth +# # ax.annotate('Sun', (sun[0]+2e7, sun[1]+2e7)) +# # ax.annotate('Earth', (earth[0]+2e7, earth[1]+2e7)) +# ax.annotate('L1', (L1[0]+2e7, L1[1]+2e7)) +# ax.annotate('L2', (L2[0]+2e7, L2[1]+2e7)) +# ax.annotate('L3', (L3[0]+2e7, L3[1]+2e7)) +# ax.annotate('L4', (L4[0]+2e7, L4[1]+2e7)) +# ax.annotate('L5', (L5[0]+2e7, L5[1]+2e7)) +# +# # Set title and show plot +# plt.title('Positions of Lagrange Points L1 to L5, Sun and Earth') +# plt.show() \ No newline at end of file diff --git a/sim_scenes/science/parabolic_curve.py b/sim_scenes/science/parabolic_curve.py index 4096dc6d0e212cf0a748eb82ea80be44fe61f609..dcb0e353049f4b886a4b76ccb55ab767dd67db4f 100644 --- a/sim_scenes/science/parabolic_curve.py +++ b/sim_scenes/science/parabolic_curve.py @@ -6,8 +6,8 @@ # link :https://gitcode.net/pythoncr/ # python_version :3.8 # ============================================================================== -from bodies import Earth -from objs import create_rock +from bodies import Moon, Earth, Body +from objs import Football from common.consts import SECONDS_PER_HOUR, SECONDS_PER_MINUTE from sim_scenes.func import ursina_run, get_vector2d_velocity, camera_look_at, two_bodies_colliding from simulators.ursina.entities.body_timer import TimeData @@ -25,11 +25,10 @@ def create_ejected_object(velocity, raduis, trail_color, gravity_only_for, angle """ # 根据速度、角度获取矢量速度(vx、vy) -> vx² + vy² = velocity² vx, vy = get_vector2d_velocity(velocity, angle=angle) - rock = create_rock(name=f'物体速度:{velocity}', mass=500, size_scale=1e3, trail_color=trail_color, - init_position=[0, raduis, 0], - init_velocity=[vx, vy, 0], - gravity_only_for=[gravity_only_for]) # 仅适用于地球的重力,物体之间重力不要受到影响 - return rock + football = Football(name=f'物体速度:{velocity}', mass=500, size_scale=1e3, trail_color=trail_color, + init_position=[0, raduis, 0], + init_velocity=[vx, vy, 0], gravity_only_for=[gravity_only_for]) # 仅适用于地球的重力,物体之间重力不要受到影响 + return football if __name__ == '__main__': @@ -38,8 +37,7 @@ if __name__ == '__main__': """ # 地球在中心位置 earth = Earth(init_position=[0, 0, 0], init_velocity=[0, 0, 0], - rotate_angle=0, rotation_speed=0, - size_scale=1, texture="earth_hd.jpg") + size_scale=1, rotation_speed=0, texture="earth_hd.jpg") raduis = earth.raduis + 300 # TODO: 4个不同的抛出速度 7.5km/s、8.5km/s、10km/s、11.2km/s(第二宇宙速度) # 粉色:velocity = 7.5,飞不出地球太远,就落地 diff --git a/sim_scenes/solar_system/speed_of_light.py b/sim_scenes/science/speed_of_light.py similarity index 96% rename from sim_scenes/solar_system/speed_of_light.py rename to sim_scenes/science/speed_of_light.py index 648ce920ca63a9125a85881c6911dc0e067f6eb1..f9254df339275196a2f1f48f7214f50ce17c26ad 100644 --- a/sim_scenes/solar_system/speed_of_light.py +++ b/sim_scenes/science/speed_of_light.py @@ -8,7 +8,7 @@ # ============================================================================== from sim_scenes.func import ursina_run, create_solar_system_bodies, create_light_ship from common.consts import LIGHT_SPEED -from sim_scenes.solar_system.speed_of_light_init import SpeedOfLightInit +from sim_scenes.science.speed_of_light_init import SpeedOfLightInit # TODO: 三种不同的摄像机视角 camera_follow_light = None # 摄像机固定,不会跟随光 diff --git a/sim_scenes/solar_system/speed_of_light_init.py b/sim_scenes/science/speed_of_light_init.py similarity index 100% rename from sim_scenes/solar_system/speed_of_light_init.py rename to sim_scenes/science/speed_of_light_init.py diff --git a/simulators/ursina_simulator.py b/simulators/ursina_simulator.py index e3f54efd906a271c298714f1a026acdbca369074..390c010b4fcf331c40e58d8a91ed234627e4342a 100644 --- a/simulators/ursina_simulator.py +++ b/simulators/ursina_simulator.py @@ -7,7 +7,7 @@ # python_version :3.8 # ============================================================================== # pip install -i http://pypi.douban.com/simple/ --trusted-host=pypi.douban.com ursina -from ursina import Ursina, window, Entity, Grid, camera, application, color, distance, Audio +from ursina import Ursina, window, Entity, Grid, camera, application, color, distance, Audio, Animation import itertools from common.image_utils import find_texture @@ -81,7 +81,40 @@ class UrsinaSimulator(Simulator): if rotation_z is not None: body.planet.rotation_z = rotation_z + def body_visible(visible): + body.planet.enabled = visible + + @property + def body_visibled(): + return body.planet.enabled + + # Explosion animation + def body_explode(target=None): + # from panda3d.core import GeomUtils + if body.planet.enabled: + body.planet.enabled = False + explosion_file = find_file("images/explosion") + explosion_file = os.path.join(explosion_file, "explosion") + # volume = body.planet.model.volume + volume = pow(body.planet.model.get_bounds().volume, 1 / 3) / 2000 + ani = Animation(explosion_file, + position=body.planet.position, + scale=volume * 2, fps=6, + loop=False, autoplay=True) + + if target is not None: + if hasattr(target, "planet"): + if hasattr(target.planet, "main_entity"): + ani.look_at(target.planet.main_entity) + else: + ani.look_at(target.planet) + else: + ani.look_at(target) + body.look_at = body_look_at + body.set_visible = body_visible + body.explode = body_explode + body.visibled = body_visibled # def get_bodies_max_distance(self, body_views): # max_distance = 0