単純な物理エンジンを2Dで書いています。私の最初の目標は、衝突検出を機能させることです。私のオブジェクトは最終的にプリミティブシェイプで構成されることはわかっていますが、私は疑問に思いました-衝突検出ライブラリは、「rayAndLine」、「rectangleRectangle」、「rectangleCircle」などの特別なケース関数の束で構成されるのでしょうか、または形状を作成するために使用されるプリミティブに関係なく機能する、衝突検出のための共通の基盤となるフレームワークはありますか?
単純な物理エンジンを2Dで書いています。私の最初の目標は、衝突検出を機能させることです。私のオブジェクトは最終的にプリミティブシェイプで構成されることはわかっていますが、私は疑問に思いました-衝突検出ライブラリは、「rayAndLine」、「rectangleRectangle」、「rectangleCircle」などの特別なケース関数の束で構成されるのでしょうか、または形状を作成するために使用されるプリミティブに関係なく機能する、衝突検出のための共通の基盤となるフレームワークはありますか?
回答:
衝突検出を機能させることは、2D物理エンジンの優れた最初の目標です。n次元関連のアルゴリズムの量にもかかわらず、2Dのすべてのルールが3Dで機能するわけではないので、特定の時点でそれらを特殊化する必要があります(詳細を行う)クロス積が3DでJacobiのアイデンティティのみをどのように満たすかなどの特定のバリアント。
あなたの質問は、本質的に2D物理学ではなく、アーキテクチャとフレームワークの設計に関するものです。そのため、これらのピースがどのように使用されるかについて、建物で何を心に留めておくべきかという懸念があります。基本的に、エンジン/ライブラリ/フレームワークを構築するメンタリティを別のプロジェクトでの使用から切り離す必要があります。
解決エンジンの設計: 任意の数学エンジンでは、基本的に値をいくつかの関数に入れたいので、得られた値が興味深いシミュレーションを行うのに役立つことが期待されます。
このプロセスのコア要素は可能な限り抽象的である必要がありますが、アトミック要素(データ/メソッドの最小の有用な部分)は個々の目的に固有であり、一緒に構成するのに役立つ必要があります。私たちの場合、ほぼ唯一の有用なアトミックは2Dベクトルです。これは、(x、y)構造の式を可能にするオブジェクトの単一クラスである必要があり、2Dでのベクトル計算に役立つすべての基本的な数学演算のメソッドを持っています。加算、減算、正規化、通常(垂直)、クロス積、ドット積、大きさ/長さ、その他、ベクトル->ベクトル演算またはベクトル->実数演算に固有の、遭遇するその他すべて。クラスベースの言語を使用している場合、簡単なclass Vector
、これらをそれぞれメンバー関数または演算子のオーバーロードとしてコードが非常に効果的です。
すべてのアトミックタイプが構築されたら、それらのアルゴリズムをアトミックタイプの上にある別のレイヤーに構成しますVector
。さんへの私の行くようになりLine
とCurve
。ここでは、a Curve
はこれの範囲外であり、多くの特殊化が必要であると決定します(上で参照した概念で、多くの特殊なケース関数の作成と呼びます)。からVector
もRectangle
4をVector
プリミティブとして構成Circle
し、a Vector
とa を使用してベクトルから構成しradius
、次にPolygon
from 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のような一般的なものは、ユースケースに応じて、され、すべて単純にどちらかの真/偽の値を返す、またはのようなリレーショナルオブジェクトを返す必要がありManifold
、Joint
、CollisionObject
コネクションを持っていることになるなど2つの形状が衝突していることが判明し、衝突の深さや速度など、衝突を解決するために必要な形状に関する情報(マニホールドに必要なデータは、使用する解決方法によって異なります)。次に、aに渡すオブジェクトは、a Solver
のみを受け入れManifold
、形状に関する特定の情報を受け入れないことで、衝突する可能性のあるすべての形状の違いを抽象化する必要があります。
要約は、Solver
かかるManifold
いくつかのプリミティブの衝突によって生成されるA
いくつかのプリミティブとB
(A B VS)第1の広範な相(全世界VS)グループ化し、次に狭い位相検出を用いて、及び形状は、非ポリゴン特化されなければならないである場合、Solver
次いで、いずれかの新しい生成しますVector
s衝突した図形の位置と速度、またはPhysicsEnvironment
またはWorld
が子の衝突を解決するために使用できるオブジェクトの場合、最終的にを更新QuadTree
し、次のフレームでこのプロセスを繰り返します。衝突する両方の形状がポリゴンの場合、特殊化はパフォーマンスの向上を考慮してのみ行う必要があります。それ以外の場合は、単に分離軸定理を使用します。
Vector direction,Magnitude
はPoint x,y
、がVector
提供する操作の一部を単に無視する場合、a と見なすことができます。これを実行することの最良の部分は、これらの操作を無視できるためです。角運動量などを決定したい場合は、オブジェクトタイプを変更しません。ゲーム開発者が「ポイント」と呼んでいる数学者は実際に「ベクトル」と呼んでいるので、それはほとんど趣味の問題です。だからそれをあなたが望むものと呼んでください、重要なことはそれが提供するものです。
typedef
ベクターから単純に定義するか、「ポイント」という用語の別名を「ベクター」と同じことを意味します。