class SolarSystem: def __init__(self, radius, name, time_step, n_bodies): self._radius = radius self._name = name self._body_list = [] self._f_matrix = np.zeros(shape=(3, n_bodies)) self.a_matrix = np.zeros(shape=(3, n_bodies)) self.dt = time_step self._n_bodies = n_bodies self._analytics = Analytics() self._acceleration_analytics = Analytics() self._velocity_analytics = Analytics() self._t = 0 def add_body(self, body): if len(self._body_list) > self._n_bodies: print( f"Cannot exceed no. bodies specified in instantiation of solar system ({self._n_bodies})" ) return self._body_list.append(body) def net_forces(self): """ produces a matrix of force components for all bodies """ self._f_matrix.fill(0) count = 0 for body in self._body_list: for body2 in self._body_list: if body != body2: net_force = Physics.gravitational_force( body.get_mass(), body2.get_mass(), self.euclidean_distance(body.get_position(), body2.get_position()), self.get_dist_change(body.get_position(), body2.get_position())) self._f_matrix[:, count] += net_force count += 1 self._analytics.add_data(self._t, la.norm(self._f_matrix[:, 1])) def acceleration(self): """ updates acceleration matrix - ax, ay, az for each body """ self.a_matrix.fill(0) for i, body in enumerate(self._body_list): self.a_matrix[:, i] = self._f_matrix[:, i] / body.get_mass() self._acceleration_analytics.add_data(self._t, la.norm(self.a_matrix[:, 1])) def velocity(self): """ updates velocity """ for i, body in enumerate(self._body_list): v = Physics.velocity(body.get_velocity(), self.dt, self.a_matrix[:, i]) body.set_position(v, self.dt) if i == 1: self._velocity_analytics.add_data(self._t, la.norm(v)) self._t += self.dt self.render() @staticmethod def get_dist_change(pos1, pos2): """ returns difference in position: x = [dx, dy, dz] """ return pos1 - pos2 @staticmethod def euclidean_distance(pos1, pos2): """ calculates Euclidean distance between two particles """ return la.norm(pos1 - pos2) def render(self): """ draws new position of all particles """ for body in self._body_list: body.draw_update() def plot(self): self._acceleration_analytics.draw("Acceleration of a planet by time", "Acceleration (ms^-2)") self._analytics.draw("Force exerted on a planet by time", "Force (N)") self._velocity_analytics.draw("Velocity of a planet by time", "Velocity (ms^-1)")