0

我在当前的台球模拟中为简单的 2D 碰撞检测和处理编写了一个程序,但是它正在寻找一个涉及适当物理的解决方案,即用于碰撞的牛顿运动定律。到目前为止我所拥有的,它不保存动量并简化物理学是

    def collide(ball1,ball2):
        dx = ball1.x - ball2.x
        dy = ball1.y - ball2.y

        dist = (dx)**2+(dy)**2
       if dist < (ball1.radius + ball2.radius)**2:

            tangent = atan2(dy, dx)
            angle = 0.5 * pi + tangent

            angle1 = 2*tangent - ball1.angle
            angle2 = 2*tangent - ball2.angle

            speed1 = ball2.speed*e
            speed2 = ball1.speed*e

            (ball1.angle, ball1.speed) = (angle1, speed1)
            (ball2.angle, ball2.speed) = (angle2, speed2)

            ball1.x += sin(angle)
            ball1.y -= cos(angle)
            ball2.x -= sin(angle)
            ball2.y += cos(angle)

我必须进行碰撞的是,bounce() 用于撞墙

    running = True
    while running:
        background()

        for i,ball in enumerate(balls,1):
            ball.bounce()
            ball.move()
            for ball2 in balls[i:]:
                collide(ball,ball2)
            ball.display()


        pygame.display.flip()

我对此还是很陌生,所以请更改无用/愚蠢的内容

4

2 回答 2

1

我记得我不久前做了一个简单的台球模拟器。正如您所提到的,这是出于教育目的,我将把您从整个代码中解放出来(而且我也不必为它挖掘:))

但基本上,我记录了自上一帧以来已经过去了多长时间。在给定每个球的速度向量的情况下,我利用这段时间找出每个球的新位置。对于帧中的碰撞,我必须确定两个球碰撞的确切时间,然后在该确切时间应用每次碰撞。伪代码看起来像:

while running:
  frame_time_ms = time elapsed since last frame
  collisions = all collisions that will happen during this frame, with the exact time of collision. (1)
  while collisions:
    collision = first collision in collisions
    collision_time_ms = time of collision (1)
    move all balls to collision_time_ms
    collide the two balls in the collision (2)
    collisions = all remaining collisions after the time of collision (1)
  move all balls to the end time of the frame

因此,您需要带回您的几何和物理知识,以找出关键公式:

  1. 给定一个框架(或框架的一部分)中两个球的开始和结束位置,它们是否会发生碰撞,以及它们会在哪一点发生碰撞。记得在这里也包括球的半径。这将为您提供碰撞时间。
  2. 给定两个球在精确的碰撞位置,它们的新速度向量之后会是什么样子。一些提示是使用弹性碰撞,并试验它的实际弹性: http ://en.wikipedia.org/wiki/Elastic_collision对于奖励积分,您还可以包括球的旋转 :)

祝你好运!=)

于 2013-01-21T22:36:47.250 回答
0

圆对圆碰撞很简单。取中心点坐标,减去它们以确定每个圆之间的距离。

然后,如果距离大于两个圆半径之和,则它们不接触。如果相等,它们就会接触,如果小于,它们就会重叠。

简单地说,如果他们正在接触,让他们互相排斥。您可以通过几种方式做到这一点。如果你跟踪他们移动的方向,让他们向相反的方向移动。

至于墙壁,只需将每个墙壁与 > < 语句一起使用。因此,如果一个圆的 pos 的 x 坐标小于西墙,则它已经通过了那堵墙。再一次,让他们击退墙壁。

Circle Collison 非常简单,但是如果您想做其他形状,这将是难以置信的困难。除非你只是在这些形状周围挖圈或使用像素完美碰撞(这是非常高的性能需求。)

如果您想要高度准确的非圆碰撞,请获取物理引擎。

于 2014-09-09T01:12:43.223 回答