Reputation: 138
I program a solar system. ATM all the planet interact with the sun(Gravitation). Now I also want that the every planets interacts with all the other planets ( How it is in reality). I thought I could do that with a double for-loop. I tried it out but it didn't work. Could you help me? I think the mistake has something to do that with sun the planets had a fix point. But now its just always planet to planet. But I dont really know... Here is my code:
from vpython import *
#Konstanten zum rechnen
s_rad0 = 6.9e8
s_rad1 = 30 * s_rad0
e_rad = s_rad1 * 0.9
m_rad = e_rad * 0.4
ae = 200 * s_rad0 #1 Astr. Einheit bezieht sich auf Ent. Sonne-Erde
ae2 = 200 * s_rad0 #bezieht sich auf Ent. Sonne-Mond
g = 6.6725e-11
framerate = 100
#array liste von Planeten
planets = []
class Sphere(object):
def __init__(self, pos, radius, make_trail):
self.pos = pos
self.radius = radius
self.make_trail = make_trail
class planet(Sphere):
def __init__(self, pos, radius, make_trail, mass, velocity):
super().__init__(pos, radius, make_trail)
self.mass = mass
self.velocity = velocity
planetSphere = sphere (pos = self.pos, radius = self.radius, make_trail = self.make_trail, mass = self.mass, velocity = self.velocity)
sun = planet(pos=vec(0,0,0),radius=s_rad1*1.5, make_trail=True, mass=2e30, velocity=vec(0,0,0))
mercury = planet(pos=vec(ae/3,0,0), radius=s_rad1/1.5, make_trail=True, mass=3.25e23, velocity=vec(0,0,-47000))
venus = planet(pos=vec(ae/1.6,0,0), radius=s_rad1/1.3, make_trail=True, mass=4.9e24, velocity=vec(0,0,-35000))
earth = planet(pos=vec(ae,0,0), radius=e_rad, mass=5.9e24, make_trail=True, velocity=vec(0,0,-25000))
mars = planet(pos=vec(ae*1.52,0,0), radius=s_rad1/1.8, make_trail=True, mass=6.4e23, velocity=vec(0,0,-24000))
jupiter = planet(pos=vec(ae*5.18,0,0), radius=s_rad1/1.2, make_trail=True, mass=10e27, velocity=vec(0,0,-9678))
saturn = planet(pos=vec(ae*9.5,0,0), radius=s_rad1/1.4, make_trail=True, mass=5.7e26, velocity=vec(0,0,-7678))
uranus = planet(pos=vec(ae*19.13,0,0), radius=s_rad1/1.7, make_trail=True, mass=8.7e25, velocity=vec(0,0,-6772))
neptun = planet(pos=vec(ae*30,0,0), radius=s_rad1/1.7, make_trail=True, mass=1.02e26, velocity=vec(0,0,-5344))
pluto = planet(pos=vec(ae*39.37,0,0), radius=s_rad1/2.4, make_trail=True, mass=1.3e22, velocity=vec(0,0,-4740))
planets.extend((mercury,venus,earth,mars,jupiter,saturn,uranus,neptun,pluto))
dt = 10000
time = 0.1
while (True):
rate(framerate)
#for-Schlaufe für Berechnung jedes einzelnen Planeten
g_forceS = vec(0,0,0)
for planet in planets:
g_force = g * sun.mass * planet.mass * (sun.pos - planet.pos).norm() / (sun.pos - planet.pos).mag2
for planet in planets:
g_force = g * planet.mass * planet.mass * (planet.pos - planet.pos).norm() / (planet.pos - planet.pos).mag2
#Sonne
g_forceS -= g_force
#print(sun.pos)
#Änderung des Velocity Vektor wird zum alten addiert
#Da a=F/m // V = a*t(a*dt) 2 Geschw. vektoriell durch F/m ausgedrückt.
planet.velocity = planet.velocity + ( g_force / planet.mass) * dt #Richtungsänderung
#Diese Änderung wird zur alten Position addiert = neue Position
planet.pos += planet.velocity * dt
sun.velocity = sun.velocity + ( g_forceS / sun.mass) * dt #Richtungsänderung
sun.pos += sun.velocity * dt
Upvotes: 0
Views: 199
Reputation: 138
I have now this solution and its working
dt = 10000
time = 0.1
while (True):
rate(framerate)
for planet in planets:
g_force = vec(0,0,0)
for planet1 in planets:
if planet != planet1:
g_force += g * planet1.mass * planet.mass * (planet1.pos - planet.pos).norm() / (planet1.pos - planet.pos).mag2
#print((sun.pos - planet.pos).mag2)
#Änderung des Velocity Vektor wird zum alten addiert
#Da a=F/m // V = a*t(a*dt) 2 Geschw. vektoriell durch F/m ausgedrückt.
planet.velocity = planet.velocity + ( (g_force) / planet.mass) * dt
#Diese Änderung wird zur alten Position addiert = neue Position
planet.pos += planet.velocity * dt
Upvotes: 0
Reputation: 8131
The indentation in your question is all messed up, but as it stands it looks like you're doing the loop wrong.
for planet in planets:
g_force = g * sun.mass * planet.mass * (sun.pos - planet.pos).norm() / (sun.pos - planet.pos).mag2
for planet in planets:
g_force = g * planet.mass * planet.mass * (planet.pos - planet.pos).norm() / (planet.pos - planet.pos).mag2
g_forceS -= g_force
There are several mistakes here. You should go through your own code step by step to see what. Adding print statements will help understand. Two things to observe though. One: the variable name in the inner loop is the same as the variable in the outer loop. The outer loop sets planet
each time (i.e. 9 times) but then the inner loop overwrites it. You need to maintain the concept of one body and the other body in separate variables. Two: you only update g_forceS
once, after the inner loop runs, so this just updates using the most recent value of planet
instead of updating 9 times.
Rewrite your code to have this structure:
for body in bodies: # Update each of the bodies in turn.
force = np.zeros(3) # We need to work out the force on the body.
for other_body in bodies: # The force is the result of all the other bodies.
if other_body is not body: # The main body doesn't count as another body.
force += gravity(body, other_body)
body.update(force) # Update the body according to the force on it.
Upvotes: 2