Skip to content

Instantly share code, notes, and snippets.

@marten-voorberg
Created October 4, 2017 11:38
Show Gist options
  • Save marten-voorberg/2f9315bc55675829b0557f811c9a5d64 to your computer and use it in GitHub Desktop.
Save marten-voorberg/2f9315bc55675829b0557f811c9a5d64 to your computer and use it in GitHub Desktop.
Blablabla
import math
def calc_gravitational_force(mass1, mass2, distance):
if distance == 0:
return 0
return 6.67e-11 * mass1 * mass2 / distance ** 2
class Vector2:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return 'Vector2({}, {})'.format(self.x, self.y)
def __add__(self, other_vector):
return Vector2(
self.x + other_vector.x,
self.y + other_vector.y
)
def __sub__(self, other_vector):
return Vector2(
self.x - other_vector.x,
self.y - other_vector.y
)
def __mul__(self, number):
return Vector2(
self.x * number,
self.y * number
)
def __truediv__(self, number):
return Vector2(
self.x / number,
self.y / number
)
# We cannot use the __len__ method because that method always has to return an integer,
# whilst the length of a vector can be a float too
def get_length(self):
return math.sqrt(self.x ** 2 + self.y ** 2)
# The unit vector of a vector is a vector with the same direction, but with a length of 1
def get_unitvector(self):
return self / self.get_length()
# Calculate the distance from this vector to another vector
def calc_distance_to(self, other_vector):
vector_between = other_vector - self
return vector_between.get_length()
class Body:
def __init__(self, position, velocity, mass):
self.position = position
self.velocity = velocity
self.mass = mass
self.resulting_force = Vector2(0, 0)
# The index of this dictionary will be the index of the other body in the body array
# The content will be the force from that body
self.forces_to_other_bodies = {}
# Temporary value which will be replaced later
self.index = -1
self.calculated_body_indexes = []
def __repr__(self):
return 'Body at {} with mass of {}kg'.format(self.position, self.mass)
def update_position(self, dt):
self.position += self.velocity * dt
def update_velocity(self, dt):
# F_res = m / a
acceleration = self.resulting_force / self.mass
delta_velocity = acceleration * dt
self.velocity += delta_velocity
def get_gravitational_force_to(self, other_body):
if not other_body.index in self.calculated_body_indexes:
vector_between = other_body.position - self.position
distance_between = vector_between.get_length()
direction_of_force = vector_between.get_unitvector()
magnitude_of_force = calc_gravitational_force(self.mass, other_body.mass, distance_between)
gravitational_force = direction_of_force * magnitude_of_force
# Add calculated gravitational force to 'the forces_to_other_body' dictionary for optimisation
other_body.calculated_body_indexes.append(self.index)
other_body.resulting_force += gravitational_force * -1
return gravitational_force
def set_resulting_gravitational_force(self, bodies):
self.resulting_force = Vector2(0, 0)
for body in bodies:
if body is not self:
self.resulting_force += self.get_gravitational_force_to(body)
# After we have calculated the resulting force the values in 'forces_to_other_bodies' have been
# used and are now outdated so we clear the dictionary to save memory
self.calculated_body_indexes = []
# Debugging
if __name__ == '__main__':
body1 = Body(Vector2(0, 0), Vector2(0, 0), 10e20)
body2 = Body(Vector2(10e10, 0), Vector2(0, 0), 10e20)
body3 = Body(Vector2(-10e10, 0), Vector2(0, 0), 10e20)
bodies = [body1, body2, body3]
for body in bodies:
body.set_resulting_gravitational_force(bodies)
print(body1.resulting_force)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment