【问题标题】:How to achieve that planets are influenced by the gravitation of other planets and not only sun?如何实现行星受到其他行星引力的影响,而不仅仅是太阳?
【发布时间】:2018-09-06 20:41:37
【问题描述】:

我编写了一个太阳系。 ATM 整个星球都与太阳相互作用(万有引力)。现在我还希望每个行星都与所有其他行星相互作用(现实中的情况)。我想我可以用双 for 循环来做到这一点。我试过了,但没有用。你可以帮帮我吗?我认为这个错误与太阳有关,行星有一个固定点。但现在它总是行星到行星。但我真的不知道... 这是我的代码:

    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 

【问题讨论】:

标签: python for-loop math astronomy vpython


【解决方案1】:

您问题中的缩进都搞砸了,但就目前而言,您似乎做错了循环。

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

这里有几个错误。您应该逐步检查自己的代码以查看内容。添加打印语句将有助于理解。不过要注意两件事。一:内循环中的变量名与外循环中的变量相同。外循环每次(即 9 次)设置planet,但随后内循环会覆盖它。您需要在单独的变量中维护一个主体和 另一个 主体的概念。二:你只更新一次g_forceS内部循环运行之后,所以这只是使用planet的最新值更新,而不是更新9次。

重写你的代码以获得这个结构:

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.

【讨论】:

  • 为什么是 np.zeros(3) ?
  • 因为力是 3 维空间中的向量。它从 0 开始,然后向其添加更多 3 向量。尽管您可以使用不同数量的维度,例如2 如果您想将所有对象放在一个平面中。
  • @Denziloe 几乎完成了,所以 +1 但body.update(force) 应该在初始O(n^2) 强制计算之后的单独循环中。那也要求部队是行星的一员!!!否则更新将拧紧尚未处理的行星的计算。这是一个常见的错误,导致模拟每次迭代都会将行星位置向某个方向移动,因此太阳系会飘走......而且它还会破坏轨道的形状和周期......
  • @Spektre 是的,我只是想正确编码原始问题中的内容,但正如您所说,它可能会出现物理问题,因为一些更新的位置用于计算力。这也可以通过给每个身体一个“下一个位置”属性来解决,然后只在最后更新所有的真实位置。
  • @Denziloe 这种方法还有另一个缺点,但它可以通过计算的微小变化而显着减少,请参阅Edit3: Improving Newton d'Lambert integration precision even more
【解决方案2】:

我现在有了这个解决方案及其工作

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 

【讨论】:

    猜你喜欢
    • 2011-10-25
    • 2014-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-03
    • 1970-01-01
    • 1970-01-01
    • 2018-09-25
    相关资源
    最近更新 更多