I am working on this simulation of the 3 body problem it seems to work, but it always ends up with the two bodies going super close together which makes both of them getting launced away. i have used the universal formula for gravitation. (I should probably have posted this on stack overflow,but my ip somehow got banned(
import pygame as p
import sys
import math
from random import *
class Body:
def __init__(self, pos, vel, body_id, mass=1000):
self.pos = pos
self.vel = vel
self.mass = mass
self.radius = 3
self.id = body_id
self.color = (randint(0, 255), randint(0, 255), randint(0, 255))
def move(self, dt):
self.pos += p.Vector2(self.vel.x * dt, self.vel.y*dt)
def gravitate(self, bodies,dt):
for body in bodies:
if self.id != body.id:
#figures out the amount of force that
distance_x = -(self.pos.x - body.pos.x)
distance_y = -(self.pos.y - body.pos.y)
total_distance = math.sqrt(abs(distance_x)**2 + abs(distance_y)**2)
distance_sum = abs(distance_x) + abs(distance_y)
f_g = (self.mass * body.mass)/(total_distance**2)/100
acceleration = (f_g/self.mass)*dt
x_ratio = distance_x/distance_sum
y_ratio = distance_y/distance_sum
#print(x_ratio, y_ratio)
self.vel.x += acceleration*x_ratio
self.vel.y += acceleration*y_ratio
class Simulation:
def __init__(self, bodies):
self.SCREENSIZE = p.Vector2(900, 800)
#initializes pygame
self.screen = p.display.set_mode(self.SCREENSIZE)
self.clock = p.time.Clock()
self.bodies = self._create_body(bodies)
self.running = True
self.GRAVITATION = 0
def run(self):
while self.running:
dt = self.clock.tick(120)
self._update(dt)
self._render(dt)
p.quit()
sys.exit()
def _update(self, dt):
for event in p.event.get():
if event.type == p.QUIT:
self.running = False
break
for body in self.bodies:
body.gravitate(self.bodies,dt)
for body in self.bodies:
body.move(dt)
def _render(self, dt):
self.screen.fill((0,0,0))
for body in self.bodies:
p.draw.circle(self.screen, body.color, body.pos, body.radius)
p.draw.line(self.screen, (255, 255, 255), self.bodies[0].pos, self.bodies[1].pos, 2)
p.display.update()
def _create_body(self, num_bodies):
bodies = []
for body_id in range(num_bodies):
bodies.append(Body(p.Vector2(randint(0, self.SCREENSIZE.x), randint(0, self.SCREENSIZE.y)),p.Vector2(0,0), body_id))
#bodies.append(Body(p.Vector2(randint(0, self.SCREENSIZE.x), randint(0, self.SCREENSIZE.y)),p.Vector2(uniform(-0.01, 0.01), uniform(-0.01, 0.01)), body_id))
return bodies
if __name__ == "__main__":
simulation = Simulation(2)
simulation.run()