Adam Closs
Adam Closs

Reputation: 39

I have coded a gravity sim that makes 2 equal sized orbs come together but

when the orbs come to close they start to stutter oddly how could i fix that

from random import Random, randint, random
from fractions import Fraction
import math
import pygame
import sys
pygame.init()
screen = pygame.display.set_mode((800,600))
moveEvent, t = pygame.USEREVENT+1, 10
pygame.time.set_timer(moveEvent, t)
v = 0
while True:
    #mass of orbs
    m = 2e15
    #diamiter of orbs
    dia = 20
    #distance
    d = math.sqrt(pow((X_2 - X_1), 2) + pow((Y_2 - Y_1), 2))
    #gravity
    g = (6.674e-11*m*m)/pow(d, 2)
    #acceleration
    a = g/m
    rise = (Y_2 - Y_1)
    run = (X_2 - X_1)
    #slope
    slope = round(rise/run, 3)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type == moveEvent:
            v += a/100
    angle = math.atan(slope)*180/math.pi
    v_X = v*math.cos(angle)
    v_Y = v*math.sin(angle)
    print("v_X, v_Y = " + str(v_X) + ", " + str(v_Y))
   
    screen.fill((0,0,0))
    pygame.draw.circle(screen, (100,100,100), (X_1,Y_1), dia, 0)
    pygame.draw.circle(screen, (100,100,100), (X_2,Y_2), dia, 0)
    pygame.display.update()
    X_1 += v_X
    Y_1 += v_Y
    X_2 -= v_X
    Y_2 -= v_Y

i need help with this(i thought it was that when the orbs got to 0 distance the gravity was undefined but that wasn't the problem)

Upvotes: 3

Views: 68

Answers (1)

Rabbid76
Rabbid76

Reputation: 210997

You have to set the velocity to 0 when the planets are close together:

if d - v < dia:
    v = 0

The distance can be computed using math.hypot

d = math.hypot(X_2 - X_1, Y_2 - Y_1)

The motion vector of the planets is the normalized direction vector (Unit vector) multiplied by the velocity:

if d != 0:
    v_X = v * (X_2 - X_1) / d
    v_Y = v * (Y_2 - Y_1) / d

And you have to calculate the new position of the planets in the timer event:

import pygame, math

pygame.init()
screen = pygame.display.set_mode((800,600))
moveEvent, t = pygame.USEREVENT+1, 10
pygame.time.set_timer(moveEvent, t)
dia = 20
m = 2e15
v = 0
X_1, Y_1 = 100, 100
X_2, Y_2 = 400, 400

run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        if event.type == moveEvent:
            d = math.hypot(X_2 - X_1, Y_2 - Y_1)
            g = (6.674e-11*m*m)/(d*d)
            a = g/m
            v += a/100
            if d - v < dia:
                v = 0
            if d != 0:
                v_X = v * (X_2 - X_1) / d
                v_Y = v * (Y_2 - Y_1) / d
            X_1 += v_X
            Y_1 += v_Y
            X_2 -= v_X
            Y_2 -= v_Y
   
    screen.fill((0,0,0))
    pygame.draw.circle(screen, (100,100,200), (X_1,Y_1), dia, 0)
    pygame.draw.circle(screen, (200,100,100), (X_2,Y_2), dia, 0)
    pygame.display.update()

pygame.quit()
exit()

See also

Upvotes: 3

Related Questions