From a0f061cfed4b825315c14bfd39f236079aae0527 Mon Sep 17 00:00:00 2001 From: t3xhno Date: Fri, 9 Feb 2024 19:47:56 +0100 Subject: [PATCH] Initial commit --- .gitignore | 1 + main.py | 51 ++++++++++++++++++++++++++++++++++++ planet.py | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 .gitignore create mode 100644 main.py create mode 100644 planet.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bee8a64 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__ diff --git a/main.py b/main.py new file mode 100644 index 0000000..84171ac --- /dev/null +++ b/main.py @@ -0,0 +1,51 @@ +# import math +import pygame +from planet import Planet + +pygame.init() + +WIDTH, HEIGHT = 800, 800 + +WINDOW = pygame.display.set_mode((WIDTH, HEIGHT)) +pygame.display.set_caption("Planet simulation") + +YELLOW = (255, 255, 0) +BLUE = (0, 0, 255) +RED = (255, 0, 0) +GRAY = (80, 78, 81) +WHITE = (255, 255, 255) + +def main(): + run = True + clock = pygame.time.Clock() + + + sun = Planet(0, 0, 30, YELLOW, 1.98892e30, True) + earth = Planet(-1 * Planet.AU, 0, 16, BLUE, 5.9742e24) + earth.y_vel = 29.783e3 + mars = Planet(-1.524 * Planet.AU, 0, 12, RED, 6.39e23) + mars.y_vel = 24.077e3 + mercury = Planet(0.387 * Planet.AU, 0, 8, GRAY, 3.3e23) + mercury.y_vel = -47.4e3 + venus = Planet(0.723 * Planet.AU, 0, 14, WHITE, 4.8685e24) + venus.y_vel = -35.02e3 + + planets = [sun, earth, mars, mercury, venus] + + while run: + # Cap the loop at 60 Hz + clock.tick(60) + WINDOW.fill((0, 0, 0)) + + for event in pygame.event.get(): + if event.type == pygame.QUIT: run = False + + for planet in planets: + planet.update_position(planets) + planet.draw(WINDOW) + + pygame.display.update() + + pygame.quit() + +main() diff --git a/planet.py b/planet.py new file mode 100644 index 0000000..c15dd65 --- /dev/null +++ b/planet.py @@ -0,0 +1,77 @@ +import pygame +import math + +# FONT = pygame.font.SysFont("dejavu", 16) + +WIDTH, HEIGHT = 800, 800 + +class Planet(): + # Astronomical unit (~ dist Earth - Sun) + AU = 149.6e6 * 1000 + G = 6.67428e-11 + SCALE = 250 / AU # 1 AU = 100 px + TIMESTEP = 3600 * 24 # 1 day + + def __init__(self, x, y, radius, color, mass, isSun = False) -> None: + self.x = x + self.y = y + self.radius = radius + self.color = color + self.mass = mass + + self.orbit = [] + self.isSun = isSun + self.distance_to_sun = 0 + + self.x_vel = 0 + self.y_vel = 0 + + def draw(self, win): + x = self.x * self.SCALE + WIDTH / 2 + y = self.y * self.SCALE + HEIGHT / 2 + + if len(self. orbit) > 2: + updated_points = [] + for point in self.orbit: + x, y = point + x = x * self.SCALE + WIDTH / 2 + y = y * self.SCALE + HEIGHT / 2 + updated_points.append((x, y)) + pygame.draw.lines(win, self.color, False, updated_points, 2) + + pygame.draw.circle(win, self.color, (x, y), self.radius) + + # if not self.isSun: + # distance_text = FONT.render(f"{round(self.distance_to_sun / 1000, 1)}km", 1, (255, 255, 255)) + # win.blit(distance_text, (x - distance_text.get_width() / 2, y - distance_text.get_height() / 2)) + + def attraction(self, other): + other_x, other_y = other.x, other.y + distance_x = other_x - self.x + distance_y = other_y - self.y + distance = math.sqrt(distance_x**2 + distance_y**2) + + if other.isSun: self.distance_to_sun = distance + + force = self.G * self.mass * other.mass / distance**2 + + theta = math.atan2(distance_y, distance_x) + force_x = math.cos(theta) * force + force_y = math.sin(theta) * force + + return force_x, force_y + + def update_position(self, planets): + total_fx = total_fy = 0 + for planet in planets: + if self == planet: continue + fx, fy = self.attraction(planet) + total_fx += fx + total_fy += fy + self.x_vel += total_fx / self.mass * self.TIMESTEP + self.y_vel += total_fy / self.mass * self.TIMESTEP + + self.x += self.x_vel * self.TIMESTEP + self.y += self.y_vel * self.TIMESTEP + + self.orbit.append((self.x, self.y))