弹性碰撞模拟
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=-1
和 big_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 时代码中出现的错误(引发的异常不相同,但问题的根源和修复它的解决方案是相同的)。
我正在尝试使用一维牛顿方程 (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=-1
和 big_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 时代码中出现的错误(引发的异常不相同,但问题的根源和修复它的解决方案是相同的)。