ラースバトラーの答えによると、単純なケースでは、最初にxまたはyの衝突をチェックするかどうかは関係ありません。ただし、これはすぐに不正確になる可能性があります。ただし、後ほど、特に形状が複雑になり、速度が速くなり、オブジェクトが増えるためです。
より洗練された衝突検出アルゴリズムの実装に興味がある場合は、以下が必要なものの概要です。
- まず、アルゴリズムはスイープとプルーニングを実行して、チェックする必要のあるオブジェクトの数を絞り込みます。すべてのオブジェクトを他のすべてのオブジェクトに対してチェックする場合、計算コストが非常に高くなることがあります。基本的に、オブジェクトが将来衝突する可能性が高いかどうかを予測します。可能性が低い場合は、計算を行いません。
- 剪定後、予備的な衝突テストを実行します。各オブジェクトには、境界の長方形または円(衝突の計算が簡単なもの)があります。2つの円/長方形が衝突するかどうかを検出することは非常に簡単で、画面の反対側にある2つのオブジェクト間の不要な計算をすばやく排除できます。
- 事前検出が行われた場合は、各形状のエッジをループして、衝突点(2つの線分の交点)を検出する必要があります。ジョンの場合、これは垂直軸と水平軸の衝突点になります。
- 衝突点のリストを取得したら、正確な衝突点を計算する必要があります。これを行うにはいくつかの方法がありますが、どれも正確になりたいかどうかに依存します。1つのオプションは、(物理インテグレーターの)時間増分を半分にし、形状の位置を再計算し、衝突点が1つだけになるまで衝突検出を再実行することです。基本的に、あなたは「影響の瞬間」を概算しています。シミュレーションに偏微分力があまりない場合は、前の積分の速度を使用し、その後に時間を半分にすることができます。
- ステップ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