衝突検出:特別なケースがたくさんありますか?


8

単純な物理エンジンを2Dで書いています。私の最初の目標は、衝突検出を機能させることです。私のオブジェクトは最終的にプリミティブシェイプで構成されることはわかっていますが、私は疑問に思いました-衝突検出ライブラリは、「rayAndLine」、「rectangleRectangle」、「rectangleCircle」などの特別なケース関数の束で構成されるのでしょうか、または形状を作成するために使用されるプリミティブに関係なく機能する、衝突検出のための共通の基盤となるフレームワークはありますか?


基礎となるフレームワークについて尋ねますが、この部分を自分で構築することを具体的に述べます。実際の質問が行われる最後の文を明確にして、自分で作成することに対する懸念を、他の人が作成した他の誰かのフレームワークを使用することからより明確に区別できますか?私も答えを提供します。
ジョシュアヘッジス2017年

フェアポイント。すべての衝突検出の基になる理論を意味しました。言い換えると、衝突検出サブシステムを作成している場合、プリミティブ/プリミティブの衝突のタイプごとに1つの関数を作成する必要がありますか、それともプリミティブが何であっても機能する単一の汎用関数がありますか?
Michael Stachowsky、2017年

ちょっと。私は答えました。SATがすべての凸多角形で機能し、すべての凹多角形が凸多角形に分解できるなど、ソリューションを非常によく一般化するものがあります。その後は、曲線、球、楕円形に特化する必要があります。以下にその概要を示します。カバーするのは大きなトピックなので、長いです。詳細やその他についてご不明な点がありましたらお知らせください
Joshua Hedges

2
異なる形状タイプの抽象化に関するこの前の質問も役立つかもしれません。
DMGregory

1
共有されるコードが多いほど良いです。コピーアンドペーストを使用している場合は、真剣に確認してください。
corsiKa 2017年

回答:


9

衝突検出を機能させることは、2D物理エンジンの優れた最初の目標です。n次元関連のアルゴリズムの量にもかかわらず、2Dのすべてのルールが3Dで機能するわけではないので、特定の時点でそれらを特殊化する必要があります(詳細を行う)クロス積が3DでJacobiのアイデンティティのみをどのように満たすかなどの特定のバリアント。

あなたの質問は、本質的に2D物理学ではなく、アーキテクチャとフレームワークの設計に関するものです。そのため、これらのピースがどのように使用されるかについて、建物で何を心に留めておくべきかという懸念があります。基本的に、エンジン/ライブラリ/フレームワークを構築するメンタリティを別のプロジェクトでの使用から切り離す必要があります。

解決エンジンの設計: 任意の数学エンジンでは、基本的に値をいくつかの関数に入れたいので、得られた値が興味深いシミュレーションを行うのに役立つことが期待されます。

このプロセスのコア要素は可能な限り抽象的である必要がありますが、アトミック要素(データ/メソッドの最小の有用な部分)は個々の目的に固有であり、一緒に構成するのに役立つ必要があります。私たちの場合、ほぼ唯一の有用なアトミックは2Dベクトルです。これは、(x、y)構造の式を可能にするオブジェクトの単一クラスである必要があり、2Dでのベクトル計算に役立つすべての基本的な数学演算のメソッドを持っています。加算、減算、正規化、通常(垂直)、クロス積、ドット積、大きさ/長さ、その他、ベクトル->ベクトル演算またはベクトル->実数演算に固有の、遭遇するその他すべて。クラスベースの言語を使用している場合、簡単なclass Vector、これらをそれぞれメンバー関数または演算子のオーバーロードとしてコードが非常に効果的です。

すべてのアトミックタイプが構築されたら、それらのアルゴリズムをアトミックタイプの上にある別のレイヤーに構成しますVector。さんへの私の行くようになりLineCurve。ここでは、a Curveはこれの範囲外であり、多くの特殊化が必要であると決定します(上で参照した概念で、多くの特殊なケース関数の作成と呼びます)。からVectorRectangle4をVectorプリミティブとして構成Circleし、a Vectorとa を使用してベクトルから構成しradius、次にPolygonfrom Vectorも構成します。PolygonからVectorではなくLine各ラインはポリゴンの最後のラインと重複するポイントを共有するため、ここここからます。

今、あなたは形を持っていますが、私たちはそれらをどうするかわかりません。

衝突検出 衝突検出は正確な科学ではなく、単一の完全なアルゴリズム(またはその他)はありません。さまざまな効果の品質を実現したり、他の方法よりも正確な方法を使用したりできる多くの方法があります。基本的には、それはいくつかの異なるレベルの懸念、したがっていくつかの異なるプロセスに分けることができます。

広いフェーズの衝突検出は、衝突する可能性のある/発生する可能性のある/行うことを気にするエリアを区分し、狭いフェーズのプロセスのためにそれらを分離する行為です。2Dでは、通常、四分木を使用することをお勧めします。そのためには、Rectangle以前に構築したAABB衝突検出を提供する必要があります。これはAxis Aligned Bounding Boxの略で、回転AしないボックスのB場合、ボックス内にボックスのどの部分も存在しないと判断するために使用しますA。これは、交差する場合、衝突Bが存在する内部にはの一部が存在できないという仮定からA生じます。

クワッドツリーは、最大深度を決定するか、オブジェクトの数量に無限の再帰深度を防ぐための再帰的なプロセスです。物理ボディを4つの領域(したがって名前)にグループ化し、各クワッドに個別にアクセスできるようにします。次に、これらの4つのクワッドのそれぞれに入力し、簡潔にするためにここでは説明しませんが、ここで利用できる同じプロセスを実行します。https//gamedevelopment.tutsplus.com/tutorials/quick-tip-use-quadtrees- to-detectly-likely-collisions-in-2d-space--gamedev-374

狭い位相衝突衝突の可能性/可能性/可能性があると判断した形状のグループを通過するプロセスであり、より離散的な衝突チェックを実行します。この時点で、オブジェクトが回転しているかどうかを気にし始めます(私はこれをカバーします。これらの衝突フェーズに合格すると、角運動量による衝突の検出と、衝突体の実際の形状を調べます。衝突のこの部分を実行するには、上記で説明したようにメソッドを特殊化します(AABBvsCircle、OBBvsCircle、CirclevsCircle、PolygonvsPoint、PolygonvsCircle、PointvsCircleなどの特定の関数を作成します)。ただし、これらのメソッド自体も階層化された方法で実行できます上記のように。

あなたの原始的な分離のチェックは、離散、特殊な衝突の検出方法やSATのような一般的なものは、ユースケースに応じて、され、すべて単純にどちらかの真/偽の値を返す、またはのようなリレーショナルオブジェクトを返す必要がありManifoldJointCollisionObjectコネクションを持っていることになるなど2つの形状が衝突していることが判明し、衝突の深さや速度など、衝突を解決するために必要な形状に関する情報(マニホールドに必要なデータは、使用する解決方法によって異なります)。次に、aに渡すオブジェクトは、a Solverのみを受け入れManifold、形状に関する特定の情報を受け入れないことで、衝突する可能性のあるすべての形状の違いを抽象化する必要があります。

要約は、SolverかかるManifoldいくつかのプリミティブの衝突によって生成されるAいくつかのプリミティブとB(A B VS)第1の広範な相(全世界VS)グループ化し、次に狭い位相検出を用いて、及び形状は、非ポリゴン特化されなければならないである場合、Solver次いで、いずれかの新しい生成しますVectors衝突した図形の位置と速度、またはPhysicsEnvironmentまたはWorldが子の衝突を解決するために使用できるオブジェクトの場合、最終的にを更新QuadTreeし、次のフレームでこのプロセスを繰り返します。衝突する両方の形状がポリゴンの場合、特殊化はパフォーマンスの向上を考慮してのみ行う必要があります。それ以外の場合は、単に分離軸定理を使用します。


1
すばらしい答え、ありがとう。しかし、私は興味があります。私は最初に、最もプリミティブなオブジェクトをそのポイントに基づいて考え、そこからベクトルを構築することを考えていました。あなたの回答から、これが必ずしも最良の選択ではなかったことがわかります。何故ですか?
Michael Stachowsky、2017年

1
その理由は、2次元ではベクトルと点が実際には同じ定義を持っているためです。a Vector direction,MagnitudePoint x,y、がVector提供する操作の一部を単に無視する場合、a と見なすことができます。これを実行することの最良の部分は、これらの操作を無視できるためです。角運動量などを決定したい場合は、オブジェクトタイプを変更しません。ゲーム開発者が「ポイント」と呼んでいる数学者は実際に「ベクトル」と呼んでいるので、それはほとんど趣味の問題です。だからそれをあなたが望むものと呼んでください、重要なことはそれが提供するものです。
Joshua Hedges

1
Cスタイル言語では、可読性のために「ポイント」の定義を使用したい場合は、実際にはtypedefベクターから単純に定義するか、「ポイント」という用語の別名を「ベクター」と同じことを意味します。
Joshua Hedges
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.