Back

Orbits

Sript description

The script below is a simple demonstration of the gravitational law. You can click to set a mass and then click again to create an other mass. At the second mass you can apply a velocity and see the trajectory. The masses are set to numbers I found that worked with pixel as metrics instead of meters.

Result

Example

Whenn the velocity is perpendicular to the gravitational force, the second mass performs uniform circular motion around the first mass.

Source Code

import math
import pygame
WIDTH, HEIGHT = 1920, 1080
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Simple Orbit Simulation")
FPS = 60
run = True
totalFrames = 0

x1 = 0
y1 = 0

x2 = -100
y2 = -100

u02x = 0
u02y = 0

ballsdrawn = 0
dragging = 0

m2 = 10**15
m1 = 10**22

Fg = 0
G = 6.673*10**-13
r = 0
θ = 0
uy = 0
def renderscreen():
    WIN.fill((0, 0, 0))

    pygame.draw.circle(WIN, (255, 255, 255), (x1, y1), 15)
    pygame.draw.circle(WIN, (255, 255, 255), (x2, y2), 15)


    if dragging == 1:
        pygame.draw.line(WIN, (255, 255, 255), (x2, y2), (mousepos[0], mousepos[1]))
        pygame.draw.circle(WIN, (0, 255, 0), (mousepos[0], mousepos[1]), 5)
    pygame.display.update()

def calculatepos():
    global u02x
    global u02y
    global x2
    global y2
    r = (math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2))*325367 #1 pixel is 520833m if 1920p is solar system size
    θ = (math.atan2((y2 - y1), (x2-x1))) * 180 / 3.14
    Fg = G*m1*m2/(r**2)
    Fgx = -math.cos(math.radians(θ))*Fg
    Fgy = -math.sin(math.radians(θ))*Fg
    ay = Fgy/m2
    ax = Fgx/m2
    u02x += ax*2*325367
    u02y += ay*2*325367
    x2 += u02x
    y2 += u02y
    print(r, u02x, u02y)
totalFrames = 0
while run:
    totalFrames += 1
    mousepos = pygame.mouse.get_pos()
    totalFrames += 1

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if ballsdrawn == 0:
                x1 = event.pos[0]
                y1 = event.pos[1]
                ballsdrawn += 1
            elif ballsdrawn == 1:
                x2 = event.pos[0]
                y2 = event.pos[1]
                ballsdrawn += 1

            if dragging == 1:
                u02x = (mousepos[0] - x2)/10
                u02y = (mousepos[1] -y2)/10
                dragging = 0

    if ballsdrawn == 2:
        dragging = 1
        ballsdrawn +=1   #don't activate again
    if dragging != 1 and ballsdrawn>1:
        calculatepos()
    renderscreen()
    pygame.time.delay(16) #16 for 60 FPS

pygame.quit()