曲線による衝突検出


12

私は、動く円とある種の静的曲線(おそらくベジェ曲線)との間の衝突検出を行いたい2Dゲームに取り組んでいます。

現在、私のゲームは静的なジオメトリとして直線のみを特徴としており、円から線までの距離を計算し、距離が円の半径より小さい場合に線を円から投影することで衝突検出を行っています。

この種の衝突検出を比較的簡単な方法で行うにはどうすればよいですか?たとえば、Box2Dにはベジェ曲線による衝突検出機能が備わっていることを知っています。完全な機能を備えた衝突検出メカニズムは必要ありません。説明したことを実行できるものだけです。


更新:すばらしい回答をありがとう!あなたが説明した方法を完全に理解するには、ベジェ曲線を読む必要があります。その後、私はあなたに戻ります。

回答:


6

29/09/2012-23:20

ここでgitリポジトリを作成しました:https : //github.com/ArthurWulfWhite/Bezier-Distance/

そこからzipとしてソースファイルをダウンロードしてください。また、FlashDevelopを使用してコンパイルできるデモも含まれています。デモを使用するには、Flash Developでプロジェクトを開き、「テストプロジェクト」をクリックします。デモの実行中にLMBをクリックして、新しいベジェ曲線と新しい円をランダム化します。

幸運を!

zipリンクは見にくい-Ctrl + Fを使用してzipと入力するだけです。このソースは、数週間の調査とプログラミングを表しています。楽しんでいただければ幸いです。


ベジェを再帰的にセグメントに分割し、それらとの衝突をチェックする予定がある場合、100,100配列(グリッド)を作成し、各セグメントを4つの最も近い正方形に配置することをお勧めします。各フレームをセグメント化します。

プログラマーとしてもゲームクリエーターとしてもbox2dの恩恵を受けると思う。

古い答え:純粋な方法。

円の中心と曲線上の最も近い点との間の距離を確認することにより、円がベジェ曲線と衝突しているかどうかを実際に確認できます。

距離の式(一般的に)

説明:

ベジェ方程式:

q(t) = (1-t) * ((1-t) * start.(x,y) + t * control.(x,y)) + t*(t * control.(x,y) + (1 - t) * end.(x,y))

これは(いくつかの代数を使って)合計できます-読みやすくするために。(x、y)を省略します(1つの数字ではなく、まだポイントです)

q(t) = (start -2 * cont + end) t^2 + (-2 * start + 2 * control) + start

ポイント(x、y)からの距離は次のとおりです。

sqrt ((q(t).x - point.x)^2 + (q(t).y - point.y)^2)

ボールに最も近いベジェ上の点を見つけるには、微分がゼロに等しいすべての点(根)を導き出し、見つける必要があります。これは3次の多項式であるため、閉じた式を使用できますが、コンピューターの浮動小数点で表される分数の精度が十分でない可能性があるため、信頼できない可能性があります。ニュートンまたはそのような性質のものを使用する方がはるかに優れています。

根を見つけるために必要な導関数は次のとおりです。

仮定:a =開始b =制御c =終了d =中心点

Wolfram Alphaを使用した誘導体

トリッキーな部分は、このポイントを増やすことです。ドット積を使用する必要があります。

必要に応じて、このためのコードがあり、衝突があるかどうかと衝突の角度がある場合にブール値を返す関数の形式でここで共有できます。このような衝突エンジンの単純な実装では、たとえば、高速で移動するボールが2つの曲線の間に挟まるなどの問題が発生する可能性があります。

現時点では避けることをお勧めします。x軸とy軸の係数を合計して加算するだけです。

ニュートンのように選択できる信頼できる方法を使用して根を見つけ、ベジェの根点から円の中心までの距離を確認し、0 <= t <= 1で、ベジェの両端の距離を確認します(開始終了)円の中心に最も近い方に、衝突があるかどうかを知らせます。

半径が最小距離よりも小さい場合、衝突が発生しています。

角度は、円の中心とベジェ上の最も近い点の間の角度です。

そうは言っても、もしあなたが本当に衝突物理学でゲームを作りたいなら、私はあなたがただベジエを反復することを勧めます

    q(t) = (1-t) * ((1-t) * start.(x,y) + t * control.(x,y)) + t*(t * control.(x,y) + (1 - t) * end.(x,y))

中央にある各ピースを十分に小さくなるまで再帰的に分割し、10ピクセル以下とすると、ボックスから大まかにベジェを構築し、物理学にBox2dを使用します。ゲームプレイをあまり向上させないタイムシンク。Box2dの使用は、過去の無数のプロジェクトで実証されています。


曲線の最短点を計算する方法は、曲線ではなく線で現在使用している方法とまったく同じです。しかし、あなたが説明した方法で曲線に対して同じことをするのは少し複雑すぎるように聞こえます。私が理解しているように、これもあなたの考えです。そして、Box2Dに関して。私はそれが素晴らしい作品だと確信しています。しかし、私のゲームの物理学は正直非常に単純であるため、本格的な物理エンジンは過剰であると判断しました。
-paldepind

ゲームにはいくつのオブジェクトがありますか?いくつ衝突することができますか?物理エンジンを使用すると、衝突時間を正確に計算するなどの大きなメリットが得られる場合があります。(フレームが離散的であり、衝突がリアルであるため(フレームをレンダリングするときに正確に発生しないでください)
AturSams

多くの場合、何か新しいものを実装するときの予期せぬ課題や、2D物理APIを使用することの美しさは、プログラミング言語を使用するのと同じであるということです。結果は非常に満足です。
AturSams

幸運を祈ります。:)
AturSams

ゲームのようなシンプルなエラストマニアを作成しています。3つの移動円と静的ジオメトリのみ。エンジン全体が完成し、うまく機能します。残された唯一のことは、この回答の助けのおかげでATMを解決しようとしている曲線を許可することです:)あなたが言及したコードを投稿してください。実生活で使用することはどれほど適切だと思いますか?ベジェを小さな線に変換するよりも良いですか?
-paldepind

7

これを行うために、私は:

  • ベジェ曲線を複数の線分に分割して保存します。

  • これらのすべてのセグメントを、カーブ全体の軸に沿った境界ボックスに配置します。

衝突検出:

1)球体がメインの境界ボックス内にあるかどうかを確認します。いいえ、衝突なし。

2)それ以外の場合、上記で計算された個々のセグメントのいずれかが球体と衝突するかどうかを確認します。参照してくださいウィキペディアからのラインと球の交差点の記事を

編集:高精度が必要で、良好なパフォーマンスが必要な場合は、曲線全体のメインバウンディングボックスを作成してから、曲線を2つのセグメントに分割することもできます(例:[0.0 - 0.5]および[0.5 - 1.0])。それらのそれぞれに対してバウディングボックスを作成し、これらの各セグメントを2つのセグメントに再分割します(したがって[0 - 0.25][0.25 - 0.5]および[0.5 - 0.75][0.75 - 1.0])。十分な精度に達するまでこのように続けます。最後にbinary tree、ルートにメインカーブの境界ボックスがあり、リーフにラインセグメントがある境界ボックスがあります。ツリー内を検索すると、O(log n)代わりに表示されますO(n)(ここでn=曲線の線分数)


このソリューションは私にとって理にかなっており、間違いなく理解するのが最も簡単であり、私はそれで解決するかもしれません。しかし、もっと「純粋な」オプションが存在するかどうかは知りたいです。
paldepind

5

直線とベジェ曲線の交差は、曲線を細分化することにより数学的に実現されます。これは、曲線の凸包特性に依存し、それを分割エトインペラのような方法で異なる制御ポリゴンを持つ小さな弧に分割することを意味します。

この記事では、http://students.cs.byu.edu/~tom/557/text/cic.pdfの要点まで説明しています。

良い点は、アルゴリズムが任意の線で機能することです。ターゲット線をOx軸に平行であるとみなすことができるように、曲線に剛体変換を適用するだけです。

同様に、ベジェアークを2つのサブアークに細分化するときに、そのような各ベジェアークの円とポリゴンをチェックできます。円は、曲線から円へのテストが意味をなすように、円弧の制御ポリゴンと交差する必要があります。


私はまだ記事を読んでいません。しかし、線とベジェ曲線の交差点から円とベジェ曲線の交差点に到達するにはどうすればよいですか?円と多角形に対する衝突をチェックすることは、私には少し複雑すぎるように聞こえます。
paldepind
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.