衝突判定のアルゴリズム


3 次元空間での 2 つの図形の衝突判定を行う計算方法の説明です。

衝突判定 / 距離計算 / 戻る / トップページ


衝突判定

2 つの図形の衝突判定 (コリジョン判定) のアルゴリズムをまとめます。 図が用意できておらず見難いですが、ご勘弁を。 太字はベクトルを表します。
 
線分と三角形
 
線分を p+tl、 三角形を (1-u-v)q0+uq1+vq2 で表します (t, u, v は媒介変数)。 Tomas Moller のアルゴリズム
[-l (q1-q0) (q2-q0)] |t|
|u|
|v|
= (p-q0)
を Cramer の公式で解きます。 0.0≦t≦1.0, 0.0≦u, 0.0≦v, u+v≦1.0 なら交差と判定します。
 
半直線と三角形
 
線分と三角形の場合と同様の計算を行います。 0.0≦t, 0.0≦u, 0.0≦v, u+v≦1.0 なら交差と判定します。
 
点と球
 
点と球の中心の距離の 2 乗を求めて、 その長さが球の半径の 2 乗以下なら交差と判定します。
 
線分と球
 
線分の始点から終点へのベクトルを v、 線分の始点から球の中心へのベクトルを c とします。
 
条件分けが多いため、計算効率が悪く、ゲームなどでの使用は非実用的です。
 
半直線と球
 
半直線の方向ベクトルを v、半直線の始点から球の中心へを c とします。
 
球と球
 
それぞれの球の中心間の距離の 2 乗を求め、 球の半径の和の 2 乗以下なら交差と判定します。
 
点と AABB (Axis Aligned Bounding Box : 辺が座標軸に平行な直方体)
 
各軸について、AABB の両面の間に点が存在すれば交差と判定します。
 
半直線と箱
 
箱の各面に関して次の判定を行います。 一つでも満たしていれば交差と判定します。
 
条件分けが多いため、計算効率が悪く、ゲームなどでの使用は非実用的です。
 
AABB と AABB
 
各軸について次の判定を行い、全て満たしていれば交差と判定します。
 
球と三角形
 
次の順に判定します。
  1. 三角形を含む平面と球の中心との距離が球の半径を越えていたら 非交差と判定します。
  2. 球の中心から三角形を含む平面へ下ろした足を p+t(-n)、 三角形を (1-u-v)q0+uq1+vq2 で表します (t, u, v は媒介変数、n は三角形の法線)。 Tomas Moller のアルゴリズム
    [n (q1-q0) (q2-q0)] |t|
    |u|
    |v|
    = (p-q0)
    を Cramer の公式で解きます。 0.0≦u, 0.0≦v, u+v≦1.0 なら交差と判定します。
  3. 球の中心と三角形の最短距離を求めて、球の半径よりも小さければ交差と判定します。 最短距離候補として、三角形の3頂点と球の中心との距離の最小値、 もしくは三角形の各辺と球の中心との距離の最小値があります。
    • u<0.0, 1.0<v, 1.0<u+v の時 q2 と球の中心との距離
    • v<0.0, 1.0<u, 1.0<u+v の時 q1 と球の中心との距離
    • u<0.0, v<0.0, u+v<1.0 の時 q0 と球の中心との距離
    が最短距離になります。 いずれでもない時、
    • u<0.0 なら線分q0q1 と球の中心との距離、
    • v<0.0 なら線分q0q2と球の中心との距離、
    • 1.0<u+v なら線分q1q2と球の中心との距離
    が最短距離になります。 ただし、この u, v の値の範囲による場合分けは、 三角形に鈍角が含まれていると破綻するため、ボロノイ領域を厳密に求めるか、 全て求めて最小値を取った方が良いです。
 
条件分けが多いため、計算効率が悪く、ゲームなどでの使用は非実用的です。
 
円柱と点
 
円柱の軸と底面の交差する 2 点を結ぶベクトルを a、 その 1 点から判定対象の点へのベクトルを v とします。 va の長さが 0.0 以下であったり、a2 以上であれば、 点は底面よりも遠くにあるので、非交差と判定します。 そうでなければ、v2-(va)2/(a2) で 点から円柱の軸への足の長さの 2 乗が求まるので、 円柱の半径の 2 乗よりも小さければ交差と判定します。
 
円柱と半直線
 
円柱の軸と半直線共に直交する線分 v を求めます。 そして、円柱の一方の底面の中心から半直線の始点へのベクトルを求めて、 v 上へ投影します。 その長さが円柱の半径よりも長ければ非交差と判定します。 半径よりも小さければ、 交点が円柱の軸方向で中に収まっており、かつ半直線上にあるかどうかで判断します。
 
円柱と線分
 
円柱の軸と線分共に直交する線分 v を求めます。 円柱の一方の底面の中心から線分の始点へのベクトルを求めて、 v 上へ投影します。 その長さが円柱の半径よりも長ければ非交差と判定します。 半径よりも小さければ、 交点が円柱の軸方向で中に収まっており、かつ線分上にあるかどうかで判断します。
 
円柱と三角形
 
円柱の軸が Y 座標になるような座標系に変換して考えます。 まず、三角形を円柱の底面でクリッピングします。 これで、X, Z 座標系へ投影して、2 次元での判定問題へ落としこめます。 三角形の各辺が円柱の円の中に含まれているかどうかを 円柱の円の中心と、三角形の辺の線分との距離が、 円柱の円の半径より小さいかどうかで判断します。 いずれも交差しない場合には三角形内部に円が含まれて いないかどうかの可能性も判断します。
 
クリッピングなど計算が複雑なために計算効率が悪く、 ゲームなどでの使用は非実用的です。
 
円柱と球
 
円柱の軸と底面の交差する2点を結ぶベクトルを a とします。 また、その 1 点から球の中心へのベクトルを v とします。
 
条件分けが多いため、計算効率が悪く、ゲームなどでの使用は非実用的です。
 
球の軌跡 (Capped Cylinder, LSS =Line Swept Sphere) と球
 
軌跡を描く球の半径分だけ球の半径を大きくし、 球と線分の交差問題に置き換えます。
 
球の軌跡と三角形
 
三角形を球の半径分太らせて、 その図形と線分との交差判定問題に置き換えます。 太った三角形は頂点を中心とした球 3 つ、辺にそった円柱 3 つ、 三角形内部の板形状に分解できるので、各々について判定します。
 
別解として、「線分対三角形」「LSS 対線分」「LSS 対球」の3つの判定を 組み合わせる方法もあるようです。
 
球の軌跡と半直線
 
球の始点と終点を結ぶ線分を軸とした円柱、 始点・終点の球の 3 つの図形と半直線の交差で判定します。
 
円柱と平面
 
円柱の底面の中心 2 点が平面に対して反対側にあるならば、交差と判定します。 円柱の軸と平面の法線の外積で、円柱を縦に切断する平面と直交する平面の 法線が求まります。 この直交平面上では円柱は長方形になっており、 また円柱と平面の最近接点はこの平面上にあります。 直交平面の法線と、円柱の軸の外積から円柱の底面の中心から最近接点へ伸びる ベクトルが 2 本求まります。 円柱の底面の中心に足すことで、円柱上の平面に最も近い点となる 候補点が 2 点求まります (直交平面上に存在し、円柱の底面の円上の点)。 この 2 点が平面に対して反対側にあれば交差と判定します。
 
球と円錐
 
球の中心、円錐の底面の中心、円錐の頂点を通る平面を考えます。 この平面と円錐の側面との交線 2 本のうち、 円錐の軸に対して球の中心に近い方を l (円錐の頂点から底面と交線の交わる点までのベクトル) とします。 このとき、平面上で、l に対して球の中心が円錐の軸側にあれば交差と判定します。 それ以外の場合、線分 l と球の中心との距離を求め、 球の半径よりも小さければ交差と判定します。

距離計算

2 つの図形の距離計算のアルゴリズムをまとめます。
 
点と点
 
2 点間を結ぶベクトルの長さです。点 a, b に対して |a-b| が距離になります。
 
点と直線
 
直線の方向ベクトル (長さ1) を v とします。 直線上の一点から点へのベクトルを p とすると、 p-(pv)v で直線から点へ最短距離で結ぶベクトルが求まるので、 これが距離になります。
 
点と三角形
 
点から三角形の 1 頂点へのベクトルを v とします。 三角形の法線と v の内積が距離になります。
 
点と線分
 
線分を v とする。線分の始点から点まで伸びるベクトルを p とする。 vp が 0.0 以上、|v|2 以下なら点から線分に伸ばした足は線分上に 存在し、その足の長さ (点と線分を含んだ直線との距離) が距離の値になる。 vp が 0.0 以下であれば、線分の始点から点までの距離が、vp が |v|2 以上なら線分の終点から点までの距離が求めたい距離になる。
 
線分と三角形
 
線分を p+tl、 三角形を (1-u-v)q0+uq1+vq2 で表します (t, u, v は媒介変数)。 Tomas Moller のアルゴリズム
[-l (q1-q0) (q2-q0)] |t|
|u|
|v|
= (p-q0)
を Cramer の公式で解きます。 0.0≦u, 0.0≦v, u+v≦1.0 なら交差しています。 |l|t で、p から交点までの距離が求まります。
 
半直線と三角形
 
線分と三角形の場合と同様です。 0.0≦t, 0.0≦u, 0.0≦v, u+v≦1.0 なら交差しています。 |l|t で、p から交点までの距離が求まります。

戻る