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

しばらく前に簡単なビリヤード シミュレーターをやったのを思い出します。あなたが言ったように、これは教育目的のためであり、コード全体からあなたを救います(そして、私もそれを掘り下げる必要はありません:))

しかし、基本的には、最後のフレームからの経過時間を追跡しました。今回は、各ボールの速度ベクトルが与えられたときに、各ボールの新しい位置を見つけるために使用しました。フレーム内の衝突では、2 つのボールが衝突する正確な時刻を把握し、その正確な時刻に各衝突を適用する必要がありました。疑似コードは次のようになります。

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 つのボールの開始位置と終了位置が与えられた場合、それらは衝突するかどうか、およびどの時点で衝突するか。ここでは、ボールの半径も忘れずに含めてください。これにより、衝突時間が得られます。
  2. 正確な衝突位置にある 2 つのボールが与えられた場合、それらの新しい速度ベクトルは後でどのように見えるでしょうか。いくつかのヒントは、弾性衝突を使用して、実際の弾性を実験することです: http://en.wikipedia.org/wiki/Elastic_collisionボーナス ポイントとして、ボールの回転を含めることもできます :)

幸運を!=)

于 2013-01-21T22:36:47.250 に答える
0

円同士の衝突は簡単です。中心点の座標を取り、それらを差し引いて、各円の間の距離を決定します。

次に、距離が両方の円の半径の合計よりも大きい場合、それらは接触しません。等しい場合は接触しており、小さい場合は重なり合っています。

簡単に言えば、接触している場合は、互いに反発させます。これはいくつかの方法で行うことができます。それらが移動する方向を追跡している場合は、反対方向に移動させます。

壁については、各壁を > < ステートメントで使用するだけです。したがって、円の位置の x 座標が西の壁よりも小さい場合、西の壁を通過したことになります。繰り返しますが、壁をはじくだけです。

Circle Collison は非常に単純ですが、他の形状を実行しようとすると、信じられないほど困難になります。これらの形状の周りに円をピットするか、ピクセル パーフェクト コリジョンを使用しない限り (これは非常に高いパフォーマンスが要求されます)。

円以外の高精度の衝突が必要な場合は、物理エンジンを入手してください。

于 2014-09-09T01:12:43.223 に答える