diff --git a/common/system.py b/common/system.py index 315126df2a7014810de6e838ff2d13e89a5c8dcc..6fdf27365ba60733335b55dee453b216236ca1d4 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 050b898f59b55ab59033fd36cb0bc4034e8f0bcb..7135c9acdda2eb979be746234588073c745f29b3 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 5877f248e709aa542d5883d74b2bd7504ec7c336..df0a0f62a851f3f2f7f51b0322de0b0f0e0b5b1e 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)