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

円と直線の衝突

ここでは円と直線が衝突しているかどうかについてまとめていきます。

衝突ではなく円と直線の交点の求め方が知りたいという場合は、円と直線の交点に記載していますのでそちらをご覧ください。

考え方

円と直線が衝突しているかどうかを調べるには、円の中心と直線の最短距離($C$ から $H$の長さ)を求めます。

最短距離を求めるためには、円の中心と直線の最も近い点($H$)を求める必要があります。

円の中心と直線の最も近い点の求め方は、点と直線の最近傍点の求め方と同じになりますので、まず先にそちらの記事をご覧ください。

円の中心と直線の最近傍点($H$)が求まれば、そこから最短距離を求められます。あとは最短距離と円の半径を比較し、最短距離が円の半径より短ければ直線と円は当たっているとなります。

計算

円の中心を$C$、円の中心と直線の最近傍点を$H$、円の半径を $r$ とします。

$C$ から $H$ に向かうベクトル $\vec{CH}$ は $H$ の座標から $C$ の座標を引き算をすれば求まります。

$\vec{CH} = C - H$

あとは、$CH$ の長さと、円の半径 $r$ を比較し、$CH$ の長さの方が短ければ衝突しているとなります。

$|\vec{CH}| < r$ であれば衝突している。

サンプルコード

/**
 * 直線と円が当たっているかどうか
 * @param line 直線
 * @param circle 円
 */
function isHit(line:Line, circle:Circle) 
{
  // 円の中心と直線の最近傍点 p を求める
  const p = PointAndLine.getNearestPoint(circle.p, line);
 
  // 円の中心から p までの距離を d として
  // d < 円の半径 r だったら当たっている
  const d = Vector2.sub(p, circle.p).sqrMagnitude;

  return (d < circle.r * circle.r);
}