1. 無職の学び舎
  2. >
  3. 無職はゲーム数学の勉強をする
  4. >
  5. 点と円の衝突

点と円の衝突

このページでは点と円の衝突について解説していきます。

円のあたり判定は、判定も簡単で比較的処理も軽いので最もよく使われる判定方法だと思います。

考え方

$点A$:円の中心
$r$:円の半径

を動かしてみて下さい。

緑の線について、$点P$ が円の外にあるときは 円の半径 $r$ よりも長くなり、円の中にあるときは $r$ よりも短くなる事がわかると思います。

なので、緑の線が円の半径$r$よりも短ければ、点と円は当たっているとなります。

緑の線を $\vec{AP}$ とすると
$|\vec{AP}| < r$ であれば、点と円が当たっている。

$\vec{AP}$ の長さを求める

$\vec{AP}$ は $点P$ の座標から $点A$ の座標を引き算する事で求められます。

$\vec{AP} = P - A$

そしてベクトルの長さは 三平方の定理で求める事ができます。

$\vec{AP} = (x, y)$ とすると $|\vec{AP}| = \sqrt{x^2 + y^2}$

まとめ

円の半径 $r$ より $\vec{AP}$ の長さが短ければ $点P$ は円に当たっている。

$|\vec{AP}| < r$
$ = \sqrt{x^2 + y^2} < r$   :$|\vec{AP}| = \sqrt{x^2 + y^2}$ なので
$ = x^2 + y^2 < r^2 \ \ \ $   :√を外す

最後に√を外していますが、√を外さなくても計算上は問題ありません。

ただコンピューターで平方根を求める処理は重い処理なので、両辺を二乗してルートを外すことで平方根の計算を無くすという方法がよく使われます。

サンプルコード

/**
  * 点と円が当たっているかどうか
  * @param p 点
  * @param circle 円
  */
 function intercect(p:Vector2, circle: Circle)
 {
   // 円の中心から p に向かうベクトルを v とする
   const v = Vector2.sub(p, circle.p);
 
   // v が 円の半径より短ければあたっている。
   // (ベクトルの長さの二乗で判定する事で処理負荷を下げる)
   return (v.sqrMagnitude < circle.r * circle.r);
 }