
マイケル
みなさんこんにちは!
マイケルです!
マイケルです!

エレキベア
クマ〜〜〜〜〜〜

マイケル
今日も引き続き、ゲーム数学を進めていくよ!
今回は「円と線分の衝突判定」についてだ!
今回は「円と線分の衝突判定」についてだ!

エレキベア
衝突判定クマ?

マイケル
ゲームでは物体同士が衝突しているかどうかの判定処理を頻繁に行うことが多いんだ!
ゲームエンジンには、大体コライダとして標準搭載されているね!
ゲームエンジンには、大体コライダとして標準搭載されているね!

マイケル
今回は第三回までの間で学んできた、三角関数やベクトルの知識を使って、
円と線分、直線の衝突判定を行っていきます!
円と線分、直線の衝突判定を行っていきます!

エレキベア
難しそうだけどやってみるクマ〜〜〜〜
参考書籍と開発言語

マイケル
勉強にするにあたっては前回同様、下記参考書を参考にしました!

マイケル
どちらも高校数学の基礎から解説しているため、しばらく数学から離れている方でも読みやすいと思います!

エレキベア
一読してみるクマ

マイケル
そしてサンプルプログラムの実装としては p5.js を使用しています!
気になった方はこちらも使用してみてくださいね!
気になった方はこちらも使用してみてくださいね!

エレキベア
グラフィックス特化のJavaScriptライブラリクマね
円と線分の衝突判定

マイケル
それじゃ早速やっていこう!
考え方

マイケル
まず、円と線分をそれぞれ 円P 線分AB として、下記のような図で考えます!

エレキベア
見た感じ 線分PXが円と線分の最短の距離 っぽいクマね

マイケル
その通り!
線分PXを求めて、円Pの半径より短いかどうかを判定 すれば衝突しているかどうか分かりそうだね!
線分PXを求めて、円Pの半径より短いかどうかを判定 すれば衝突しているかどうか分かりそうだね!

マイケル
そして線分PXは、下記のように
「線分ABと線分APのベクトルの外積」を線分ABの長さで除算
すれば求められます!
「線分ABと線分APのベクトルの外積」を線分ABの長さで除算
すれば求められます!

エレキベア
なるほどクマ・・・
あえてAPの長さを残すことでPXの長さを求めるクマね
あえてAPの長さを残すことでPXの長さを求めるクマね
最短距離を考える

マイケル
基本的には線分PXの長さを最短距離として考えて問題ないですが、
下記のような場合には最短距離を再設定する必要があります!
下記のような場合には最短距離を再設定する必要があります!
① 線分AXの長さが負の値(線分ABのベクトルと逆方向)の場合
→線分APを最短距離として設定
① 線分AXの長さが線分ABの長さより大きい(線分ABよりも先にある)場合
→線分BPを最短距離として設定

エレキベア
線分の場合は長さに制限があるから考慮する必要があるクマね

マイケル
その通り!
そして線分AXの長さに関しては、先ほどと同じ考え方で、
「線分ABと線分APのベクトルの内積」を線分ABの長さで除算
することで求めることができるよ!
そして線分AXの長さに関しては、先ほどと同じ考え方で、
「線分ABと線分APのベクトルの内積」を線分ABの長さで除算
することで求めることができるよ!

エレキベア
これで判定に必要な値が揃ったクマね
実装

マイケル
これまでの内容を実装したものが下記になります!
↑円と線分の衝突判定処理

エレキベア
さっきの図を思い出せば意味も分かるクマね

マイケル
参考として、クラスやベクトルの処理等は下記のように実装しています!
↑位置やベクトル等のクラス

マイケル
上記ソースコードよりシミュレータを作ってみたので、
是非触って挙動を確かめてみてください!
是非触って挙動を確かめてみてください!
↑円と線分の衝突判定(※ドラッグで線分の長さを変更可)

マイケル
下記のように、衝突判定を行えていることがわかります!

エレキベア
やったクマ〜〜〜〜〜〜!!
円と直線の衝突判定

マイケル
そしておまけになりますが、円と直線の衝突判定処理 についても紹介します!
考え方

マイケル
考え方は基本的に円と線分の衝突判定と同じですが、
直線のため終点がありません。
直線のため終点がありません。

マイケル
そのため下記のように、直線の任意の位置と方向ベクトルで衝突判定を行うことになります!

エレキベア
これも線分PXが円と線分の最短の距離 っぽいクマね

マイケル
その通り!
そして線分PXは下記のように
直線Aの正規化されたベクトルと線分APのベクトルの外積
から求めることができます!
そして線分PXは下記のように
直線Aの正規化されたベクトルと線分APのベクトルの外積
から求めることができます!

エレキベア
さっきよりもだいぶシンプルクマね
実装

マイケル
そして実装したコードは下記になります!
↑円と直線の衝突判定
↑直線クラス

マイケル
こちらもシミュレータを作ったので触ってみてください!
↑円と直線の衝突判定(※ドラッグで直線の方向を変更可)

マイケル
下記のように衝突判定が行えていることが分かります!

エレキベア
線分との衝突よりもシンプルにできたクマね
おわりに

マイケル
というわけで今回は「円と線分(直線)の衝突判定」についてでした!
どうだったかな?
どうだったかな?

エレキベア
式だけ見るとややこしいクマが、図を描いてみると理解できたクマ〜〜〜

マイケル
衝突判定は少しややこしいものが多いけど、
引き出しにもなるので少しずつ覚えていこうと思う!
引き出しにもなるので少しずつ覚えていこうと思う!

エレキベア
クマもがんばるかもしれないクマ〜〜〜

マイケル
それでは今日はこの辺で!
アデュー!!!
アデュー!!!

エレキベア
クマ〜〜〜〜〜〜〜〜
【ゲーム数学】第四回 p5.jsで学ぶゲーム数学「円と線分の衝突判定」 〜完〜