【问题标题】:Solar System Simulation - Where are my calculations going wrong?太阳系模拟 - 我的计算哪里出错了?
【发布时间】:2019-05-16 15:56:21
【问题描述】:

我正在使用物理方程、x 和 y 坐标以及使用 2D 列表的字典为项目制作 2D 太阳系模拟。我正在使用 tkinter 画布来构建动画。

行星“地球”似乎从屏幕上消失了,一开始的加速度很慢,不久之后又出现了巨大的加速度。我看不到问题。

之前,我只有地球围绕太阳旋转,它以类似的方式成功地使用了方程,并通过计算出的位移的 x 和 y 分量在画布上移动了地球。字典按{(-body):[[x, y], [x velocity, y velocity], mass, [change in x displacement, change in y displacement]} 排序。如有必要,计算的值将存储或添加到此字典中的某些值。这是我正在使用的代码:

G = 6.67384 * 10 ** -11                                              
scale = 10 ** 13                                                                             
speed = 1                 
global user_status
screen = Tk()
screen.title('Solar System' + ' - ' + user_status)
screen.geometry('1300x700')

ani = Canvas(screen, width=1300, height=700)
ani.pack()
ani.create_rectangle(0, 0, 1300, 700, fill='Black')

sunx = 636
suny = 343
sun = ani.create_oval(sunx-10, suny-10, sunx+10, suny+10, fill='yellow')

earthx = 746
earthy = 343

moonx = 747
moony = 343

bodies = {'sun':  [[sunx, suny],     [0, 0],                         1.989 * 10 ** 30 * speed / scale,      [0, 0]],
          'earth':[[earthx, earthy], [0, 347.3833062 * 1.033447099], 5.972 * 10 ** 24 * speed / scale,      [0, 0]],
          'moon': [[moonx, moony],   [0, 360],                       7.34767309 * 10 ** 22 * speed / scale, [0, 0]]
          }

body_names = []
for Ω in bodies.keys():
    body_names.append(Ω)

moon = ani.create_oval(moonx - 4, moony - 4, moonx + 4, moony + 4, fill='grey70')
earth = ani.create_oval(earthx-6, earthy-6, earthx+6, earthy+6, fill='sky blue')

timestep = 0.0001

while True:
    for i in range(len(body_names)):
        body1 = body_names[i]
        x1 = bodies[body1][0][0]
        y1 = bodies[body1][0][1]
        total_Fx = 0
        total_Fy = 0
        body1_mass = bodies[body1][2]
        for j in range(len(body_names)):
            body2 = body_names[j]
            if body1 != body2:
                x2 = bodies[body2][0][0]
                y2 = bodies[body2][0][1]
                body2_mass = bodies[body2][2]

                r = sqrt(((x1 - x2) ** 2) + ((y1 - y2) ** 2))
                rx = (x1 - x2)
                angle = (acos(rx/r))

                F = (G * body1_mass * body2_mass) / (r ** 2)
                Fx = F * cos(angle)
                Fy = F * sin(angle)

                total_Fx += Fx
                total_Fy += Fy

        ax = (total_Fx / body1_mass)
        ay = (total_Fy / body1_mass)

        ux = bodies[body1][1][0]
        uy = bodies[body1][1][1]

        vx = ux - (ax * timestep)
        if x1 <= sunx:
            vy = uy + (ay * timestep)
        else:
            vy = uy - (ay * timestep)

        sx = vx * timestep * speed
        sy = vy * timestep * speed

        bodies[body1][3][0] = sx
        bodies[body1][3][1] = sy

        bodies[body1][1][0] += vx
        bodies[body1][1][1] += vy

        bodies[body1][0][0] = x1 + sx
        bodies[body1][0][1] = y1 + sy
        print(bodies[body1][1], body1)

    move_e_x = bodies['earth'][3][0]
    move_e_y = bodies['earth'][3][1]
    ani.move(earth, move_e_x, move_e_y)

    move_m_x = bodies['moon'][3][0]
    move_m_y = bodies['moon'][3][1]
    ani.move(moon, move_m_x, move_m_y)

    ani.update()

我希望物体同时绕太阳和彼此绕行,但在物体远离屏幕后我收到此错误消息:

Traceback (most recent call last):
  File "/Users/apple/Documents/School/Computer Science/NEA/NEA Programming/Solar System Simulator.py", line 380, in <module>
    simulate()                                                                               # Calls the 'simulate' function
  File "/Users/apple/Documents/School/Computer Science/NEA/NEA Programming/Solar System Simulator.py", line 290, in simulate
    r = sqrt(((x1 - x2) ** 2) + ((y1 - y2) ** 2))
OverflowError: (34, 'Result too large')

我知道这可能不是一段非常有效的代码,但我需要的只是一些有关如何以这种方式执行此操作的帮助。该问题似乎出现在位移或速度计算中。有什么想法吗?

【问题讨论】:

  • 数字太大了。尝试缩小它们。
  • 感谢您的评论,但我已经成功地使用这些数字创建了一个轨道影响,但没有字典存储系统,所以我认为这些数字不需要缩放,但我不需要知道为什么数字会变得如此之大。它似乎发生在速度或位移计算中。
  • 那么你需要做一些调试来找出计算在什么时候关闭。
  • 抱歉,我觉得这个建议并不是特别有用。我完全不知道为什么或哪里的值变得如此之大,似乎无法解释。
  • 首先找出哪个数字太大——(x1-x2)**2(y1-y2)**2。然后确定x1y1x2y2 是否符合您的预期。通过代码进行备份以查看它们是如何计算的。换句话说,手动单步执行代码并自己进行计算。在某些时候,数字会偏离您的预期。

标签: python tkinter python-3.6 simulation physics


【解决方案1】:

初始速度被接收两次:在每个循环中,初始速度被调用和使用,因此自身和新速度相加,使其每次都增加一倍以上。

现在计算新添加的速度,然后只添加一次到初始速度。行星现在在轨道上运行。目前有 9 个天体围绕太阳运行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-05
    • 2023-03-22
    • 2019-02-05
    • 2013-04-19
    • 1970-01-01
    • 1970-01-01
    • 2015-07-14
    • 1970-01-01
    相关资源
    最近更新 更多