From 87c7cc142c85ac4002e391162e9c0fba0db1b701 Mon Sep 17 00:00:00 2001 From: march3 Date: Tue, 11 Jul 2023 16:13:51 +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?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/system.py | 34 ++++++++++++++++++- sim_lab/speed_of_light_3d_speed.py | 2 +- .../science/jupiter_moon_protects_earth.py | 2 +- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/common/system.py b/common/system.py index 315126d..6fdf273 100644 --- a/common/system.py +++ b/common/system.py @@ -7,6 +7,7 @@ # python_version :3.8 # ============================================================================== import numpy as np +from numpy.linalg import norm import math from common.consts import AU, G from bodies import Body, Sun, Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto @@ -162,9 +163,40 @@ class System(object): body1.acceleration = acceleration return True + def calculate_gravitational_accelerations(self, masses, positions): + '''Params: + - positions: numpy array of size (n,3) + - masses: numpy array of size (n,) + ''' + masses = np.array(masses) + positions = np.array(positions) + mass_matrix = masses.reshape((1, -1, 1)) * masses.reshape((-1, 1, 1)) + disps = positions.reshape((1, -1, 3)) - positions.reshape((-1, 1, 3)) # displacements + dists = norm(disps, axis=2) + dists[dists == 0] = 1 # Avoid divide by zero warnings + forces = G * disps * mass_matrix / np.expand_dims(dists, 2) ** 3 + return forces.sum(axis=1) / masses.reshape(-1, 1) + def calc_bodies_acceleration(self): """ - 计算加速度 + 计算加速度(使用矩阵的方式,性能提高很多) + @return: + """ + valid_bodies = list(filter(lambda b: not b.ignore_mass, self.bodies)) + masses = [] + positions = [] + for body in valid_bodies: + masses.append(body.mass) + positions.append(body.position * 1000) + + accelerations = self.calculate_gravitational_accelerations(masses, positions) + + for idx, body in enumerate(valid_bodies): + body.acceleration = accelerations[idx]/1000 + + def calc_bodies_acceleration_bak(self): + """ + 计算加速度(性能非常低,代码保留) @return: """ # 如果快速计算成功,则无需再计算 diff --git a/sim_lab/speed_of_light_3d_speed.py b/sim_lab/speed_of_light_3d_speed.py index 050b898..7135c9a 100644 --- a/sim_lab/speed_of_light_3d_speed.py +++ b/sim_lab/speed_of_light_3d_speed.py @@ -8,7 +8,7 @@ # ============================================================================== import sys import time -from common.func import wait_for, calculate_acceleration +from common.func import wait_for from common.consts import AU from sim_scenes.func import ursina_run, create_solar_system_bodies, create_light_ship, create_3d_card from common.consts import LIGHT_SPEED diff --git a/sim_scenes/science/jupiter_moon_protects_earth.py b/sim_scenes/science/jupiter_moon_protects_earth.py index 5877f24..df0a0f6 100644 --- a/sim_scenes/science/jupiter_moon_protects_earth.py +++ b/sim_scenes/science/jupiter_moon_protects_earth.py @@ -202,7 +202,7 @@ if __name__ == '__main__': # 设置计时器的最小时间单位为年 BodyTimer().min_unit = BodyTimer.MIN_UNIT_YEARS - sim = JupiterProtectsEarthSim(comet_num=20) + sim = JupiterProtectsEarthSim(comet_num=50) # 运行前会触发 on_ready UrsinaEvent.on_ready_subscription(sim.on_ready) -- GitLab