弹性碰撞模拟

Elastic collision simulation

我正在尝试使用一维牛顿方程 (https://en.wikipedia.org/wiki/Elastic_collision) 和 pygame 来模拟弹性碰撞。 问题是,即使我转录求解的方程来改变两个物体的速度,它也不起作用(或者代码可能有问题)。 这是代码:

import pygame

pygame.init()
clock = pygame.time.Clock()

screenx,screeny = 1000,800

screen = pygame.display.set_mode([screenx,screeny])
pygame.display.set_caption("Elastic collision")

# Rectangles
small= pygame.Rect(70,433,17,17)
big = pygame.Rect(220,400,50,50)
# Masses
m_small = 1
m_big = 1
# Velocity
small_vel = 0
big_vel = -1

count = 0
start = False
sumM = m_small+m_big

run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            run = False

    screen.fill((0,0,0))

    big.x += big_vel
    small.x+=small_vel
    # If collision between small and big...
    if big.x==small.x+17:
        start=True

    if start == True:
        # ...change velocity of small and big,
        # using the elastic collision equation at each collision
        if small.x==0 or big.bottomleft<=small.bottomright:
            small_vel = (m_small-m_big)/sumM*small_vel+2*m_big/sumM*big_vel
            big_vel = (m_big-m_small)/sumM*big_vel+2*m_small/sumM*small_vel
            count += 1
            print("Small vel:", small_vel, " Big vel:", big_vel)

    # Draw the rectangles
    pygame.draw.rect(screen, (255,255,255), small)
    pygame.draw.rect(screen, (255,255,255), big)
    pygame.draw.line(screen, (255,0,0), (0,450), (1000,450),width=1)

    pygame.display.flip()
    clock.tick(60)
    pygame.display.update()

由于2个质量相等,碰撞后移动的一个应该停止,另一个应该开始移动。这没有发生。我还尝试在速度因碰撞而改变的 if 语句中编写 small_vel=-1big_vel=0 并且工作正常。

我觉得问题出在这两行:

            small_vel = (m_small-m_big)/sumM*small_vel+2*m_big/sumM*big_vel
            big_vel = (m_big-m_small)/sumM*big_vel+2*m_small/sumM*small_vel

这里big_vel是根据small_vel的新值更新的,这不是我们想要的。将 small_vel 的新值保存在临时变量中并在分配给 big_vel 后恢复它似乎可以解决问题:

            tmp_small_vel = (m_small-m_big)/sumM*small_vel+2*m_big/sumM*big_vel
            big_vel = (m_big-m_small)/sumM*big_vel+2*m_small/sumM*small_vel
            small_vel = tmp_small_vel

老实说,我没有看过数学方面的东西,我不确定这是否正是您想要的,但结果至少看起来像维基百科页面的视频。

在旁注中,您应该看看这个 post: i get an pygame.error: video system not initialised error everytime i run the program 修复关闭 window 时代码中出现的错误(引发的异常不相同,但问题的根源和修复它的解决方案是相同的)。