I made an orbit simulator in python, but it doesn't work. Objects behave strangely instead of attracting each other, plus if they have a lot of mass they fly off into infinity. Here is the code:
from tkinter import *; import math; import random; import time
root=Tk()
root.geometry("2366x720")
mouseY, mouseX = 0,0
Objectx, Objecty, Objectxvel, Objectyvel, ObjectMass = [],[],[],[],[]
for i in range(3): # numero objetos
Objectx.append(random.randint(100,1000))
Objecty.append(random.randint(100,700))
Objectxvel.append(0) #Objectxvel.append(random.randint(-30,30) / 100)
Objectyvel.append(0) #Objectyvel.append(random.randint(-30,30) / 100)
ObjectMass.append(random.randint(500,500000))
canvas=Canvas(root, bg="white")
canvas.pack(fill="both", expand=True)
def mousePos(event):
global mouseX; global mouseY
mouseX,mouseY = event.x, event.y
root.bind("<Motion>", mousePos)
mouseMass=0 # masa del circulo rojo. No es importante pero se puede cambiar por diversion
G = 6.67428e-11
while True:
canvas.delete("all")
#----------------------------- Objects ---------------------------------------------------------------------------------------
#print(range(len(Objectx)))
for Num in range(len(Objectx)):
angle = math.atan2( mouseY-Objecty[Num], mouseX-Objectx[Num] )
distance = math.sqrt( ((mouseX-Objectx[Num])**2) + ((mouseY-Objecty[Num])**2) )
Objectxvel[Num] += math.cos(angle) * G * ObjectMass[Num] * mouseMass / (distance ** 2)
Objectyvel[Num] += math.sin(angle) * G * ObjectMass[Num] * mouseMass / (distance ** 2)
Objectx[Num] += Objectxvel[Num]
Objecty[Num] += Objectyvel[Num]
if distance < 20:
if distance < 15:
Objectx[Num] -= Objectxvel[Num] * 1.5
Objecty[Num] -= Objectyvel[Num] * 1.5
Objectxvel[Num] = 0
Objectyvel[Num] = 0
else:
Objectx[Num] -= Objectxvel[Num] * 1.01
Objecty[Num] -= Objectyvel[Num] * 1.01
Objectxvel[Num] = 0
Objectyvel[Num] = 0
#----------------------------------------------------objects & objects detection--------------------------------------------
for Num2 in range(len(Objectx)):
angle = math.atan2( Objectx[Num]-Objecty[Num2], Objecty[Num]-Objectx[Num2] )
distance = math.sqrt( ((Objectx[Num]-Objectx[Num2])**2) + ((Objecty[Num]-Objecty[Num2])**2) )
#print(distance)
try:
Objectxvel[Num] += math.cos(angle) * G * ObjectMass[Num] * ObjectMass[Num2] / (distance ** 2)
Objectyvel[Num] -= math.sin(angle) * G * ObjectMass[Num] * ObjectMass[Num2] / (distance ** 2)
except:
pass
Objectx[Num] += Objectxvel[Num]
Objecty[Num] += Objectyvel[Num]
if distance < 20 and distance > 0:
try:
Objectx[Num] -= Objectxvel
Objecty[Num] -= Objectyvel
except:
pass
#Objectxvel[Num] = 0
#Objectyvel[Num] = 0
canvas.create_oval(Objectx[Num]+5, Objecty[Num]+5, Objectx[Num]-5, Objecty[Num]-5, fill="black", width=0)
#----------------------------- No Object ---------------------------------------------------------------------------------------
oval1=canvas.create_oval(mouseX+15, mouseY+15, mouseX-15, mouseY-15, fill="red", width=0)
#print(Objectx, Objecty)
root.update()
PS: to help understand the code, the first thing it does is create lists with values, like the coordinates of each object, the force of movement in x and y, etc. then inside the "While True" I have a "For Num in range(quantity of objects)" that I use to individually calculate the physics of each object with each object, accessing the element number "Num" of each list.
PD2:
Objectxvel[Num] += math.sin(angle) * G * ObjectMass[Num] * ObjectMass[Num2] / (distance ** 2) this is the law of universal gravitation. Objectx is constantly increased by Objectxy, which is constantly increased by the law of universal gravitation. The same goes for Objecty and Objectyvel.