Ragnarök
Ragnarök

Reputation: 138

How to achieve that planets are influenced by the gravitation of other planets and not only sun?

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

Answers (2)

Ragnarök
Ragnarök

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

Denziloe
Denziloe

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

Related Questions