2つの長方形間の衝突方向を決定する方法は?


7

2つの長方形の間で衝突が発生する方向を判別する方法を理解しようとしています。

1つの長方形は移動しません。もう一方の長方形は、任意の方向の速度を持っています。衝突が発生したときに、移動する長方形の位置をインパクトポイントに設定できるようにしたいと考えています。

どの方向から衝撃が発生するのかわからなくなったようです。厳密に垂直方向または水平方向に移動している場合、優れた検出を実現します。しかし、同時に両方向に移動すると、奇妙なことが起こります。

2つの長方形の間で衝突が発生する方向を決定する最良の方法は何ですか?


1
現在どのように衝突を検出していますか?
MichaelHouse

3
影響のポイントを特定しようとしているようです。1つの四角形が静止している場合、移動する四角形の移動ベクトルを逆にすると、「衝突方向」が得られると思いますか
John McDonald

回答:


9

どの方向から衝撃が発生するのかわからなくなったようです。厳密に垂直方向または水平方向に移動している場合、優れた検出を実現します。しかし、同時に両方向に移動すると、奇妙なことが起こります。

tl; dr解決策は、一度に1つの軸を移動して衝突をチェックすることです。

私もこれと同じ問題を抱えていました。ゲームループの更新フェーズは次のようになるはずです。

  • object.x + = object.vx
  • object.y + = object.vy
  • 衝突をチェック
  • 衝突への応答

ここでの秘訣は、一度に1つの軸を移動て衝突チェックすることです。あなたが言ったように、「私が厳密に垂直または水平に動いている場合、私は素晴らしい検出を管理します。」したがって、問題の99%はすでに解決済みです。ロジックを次のように変更するだけです。

  • object.x + = object.vx
  • 衝突をチェック/応答する
  • object.y + = object.vy
  • 衝突をチェック/応答する

単純なケースでは、最初にどの軸を使用してもかまいません。どちらか一方を任意に選択するのが気に入らない場合は、最初にオブジェクトの絶対速度が最大になる軸を確認するのが妥当です。


9

ラースバトラーの答えによると、単純なケースでは、最初にxまたはyの衝突をチェックするかどうかは関係ありません。ただし、これはすぐに不正確になる可能性があります。ただし、後ほど、特に形状が複雑になり、速度が速くなり、オブジェクトが増えるためです。

より洗練された衝突検出アルゴリズムの実装に興味がある場合は、以下が必要なものの概要です。

  1. まず、アルゴリズムはスイープとプルーニングを実行して、チェックする必要のあるオブジェクトの数を絞り込みます。すべてのオブジェクトを他のすべてのオブジェクトに対してチェックする場合、計算コストが非常に高くなることがあります。基本的に、オブジェクトが将来衝突する可能性が高いかどうかを予測します。可能性が低い場合は、計算を行いません。
  2. 剪定後、予備的な衝突テストを実行します。各オブジェクトには、境界の長方形または円(衝突の計算が簡単なもの)があります。2つの円/長方形が衝突するかどうかを検出することは非常に簡単で、画面の反対側にある2つのオブジェクト間の不要な計算をすばやく排除できます。
  3. 事前検出が行われた場合は、各形状のエッジをループして、衝突点(2つの線分の交点)を検出する必要があります。ジョンの場合、これは垂直軸と水平軸の衝突点になります。
  4. 衝突点のリストを取得したら、正確な衝突点を計算する必要があります。これを行うにはいくつかの方法がありますが、どれも正確になりたいかどうかに依存します。1つのオプションは、(物理インテグレーターの)時間増分を半分にし、形状の位置を再計算し、衝突点が1つだけになるまで衝突検出を再実行することです。基本的に、あなたは「影響の瞬間」を概算しています。シミュレーションに偏微分力があまりない場合は、前の積分の速度を使用し、その後に時間を半分にすることができます。
  5. ステップ4の結果は、おおよその衝突ポイントを示します(3pxなどの上限/下限内)。衝突点が複数ある場合は、それらを仮想エッジとして扱う必要があります。次に、衝突解決計算(速度、運動量、摩擦など)を実行できます。

これが誰かを助けることを願っています。

ジョンの質問に固有:

衝突アルゴリズムの欠けているステップは、ステップ#4です。私が理解していることから、長方形は斜めに交差し、2つの衝突点(1つは水平方向、もう1つは垂直方向)になります。最初に発生した衝突点の判別は、物理統合に何を使用しているかによって本当に異なります。

あなたの説明から、長方形は回転しないように聞こえ、偏微分力のようなことはそれほど問題ではありません。この場合、最初に衝突するエッジを見つけるのはかなり簡単です。ここにいくつかの擬似コードがあります:

/*
   Assume Obj1 is stationary
   Assume Obj2's velocity is -x and -y (to bottom left)
   From this, we know the collision edges are:
*/
colEdgesObj1 = [1,0]; //right, top
colEdgesObj2 = [0,1]; //left, bottom
//... where [0=left/1=right, 0=top/1=bottom]

//Calculate distances between Obj1 edges and Obj2 edges
distX = Math.Abs(Obj1[colEdgesObj1[0] ? "right" : "left"] -
                 Obj2[colEdgesObj2[0] ? "right" : "left"]);
distY = Math.Abs(Obj1[colEdgesObj1[1] ? "bottom" : "top"] -
                 Obj2[colEdgesObj2[1] ? "bottom" : "top"]);

//Calculate time object would take to go those distances
//(assuming Obj2 is the only moving object)
timeX = distX/Obj2.VelX;
timeY = distY/Obj2.VelY;

//If time is greater, that axis has been colliding longer
if timeX > timeY
    //collided X axis first
else if timeY > timeX
    //collided Y axis first
else
    //collided at a corner
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.