YAS's VB.NET Tips
 
Pythonista活用
Pythonista活用 >> 記事詳細

2019/01/18

当たり判定の後に,円が接するところまで戻す

Tweet ThisSend to Facebook | by:YAS
 下の図のように,中心の座標が  (x_{1},\;y_{1})  で半径が  r_{1}  の円O1と,中心の座標が  (x_{2},\;y_{2})  で半径が  r_{2}の円O2があるとすると,この2つの当たり判定は,三平方の定理から,(1)のような式になります。

   (x_{2}-x_{1})^2+(y_{2}-y_{1})^2  \raisebox{3}{\relstack{<}{=}}  (r_{1}+r_{2})^2\;\cdots\;\text{(1)}

   

 ①で右辺と左辺が等しい場合には問題ありませんが,多くの場合左辺が右辺よりも小さい状態で当たりが判定されます。これは2つの円が重なっている状態なので,衝突によって円の進む方向が変わっても,またすぐに当たりとして判定されてしまいます。そこで,2つの円が接した瞬間の円の中心の座標を計算で求めることにします。

「チャート式基本事項14直線のベクトル方程式」より

   \vec{OA}=\vec{a}\vec{OE}=\vec{e} とすると,

 点Aを通り, \vec{OE}  に平行な直線は,次のようなベクトル方程式で表される。

   \vec{x}=\vec{a}+t\vec{e} ( t は実数)
 

 当たり判定時の原点から円の中心へのベクトルをそれぞれ  (a_{1},\;b_{1})(a_{2},\;b_{2})  とし,円の速度ベクトルをそれぞれ (c_{1},\;d_{1})(c_{2},\;d_{2}),2つの円が接した瞬間の原点から円の中心へのベクトルをそれぞれ  (x_{1},\;y_{1})(x_{2},\;y_{2})  とすると,下のようなベクトル方程式になる。

  \begin{eqnarray}&(x_{1},\;y_{1})&=&(a_{1},\;b_{1})&+&t&(c_{1},\;d_{1})&\;\cdots\;\text{(2)}\\&(x_{2},\;y_{2})&=&(a_{2},\;b_{2})&+&t&(c_{2},\;d_{2})&\;\cdots\;\text{(3)}\end{eqnarray}
   ( t は実数)

   (2)と(3)を展開すると,
  \begin{eqnarray}&(x_{1},\;y_{1})&=&(a_{1}&+&c_{1}t,\;b_{1}&+&d_{1}t)&\;\cdots\;\text{(4)}\\&(x_{2},\;y_{2})&=&(a_{2}&+&c_{2}t,\;b_{2}&+&d_{2}t)&\;\cdots\;\text{(5)}\end{eqnaray}
   
   (4)と(5)を(1)に代入すると,
   (a_{2}+c_{2}t-a_{1}-c_{1}t)^2+(b_{2}+d_{2}t-b_{1}-d_{1}t)^2=(r_{1}+r_{2})^2\;\cdots\;\text{(6)}

   (6)で次のように置き換えると,
   A=a_{2}-a_{1}B=b_{2}-b_{1}C=c_{2}-c_{1}D=d_{2}-d_{1}R=r_{1}+r_{2}
   として代入すると,以下のようになる。

   (A+Ct)^2+(B+Dt)^2=R^2\;\cdots\;\text{(7)}

   これを展開して,
   A^2+2ACt+C^2t^2+B^2+2BDt+D^2t^2-R^2=0

   整理すると,次のような二次方程式になる。
   (C^2+D^2)t^2+2(AC+BD)t+(A^2+B^2-R^2)=0\;\cdots\;\text{(8)}

   (8)を二次方程式の解の公式  x=\frac{-b\pm\sqrt{b^2-4ac}}{2a}  に当てはめると,

   t=\frac{-2(AC+BD)\pm\sqrt{\left{2(AC+BD)\right}^2-4(C^2+D^2)(A^2+B^2-R^2)}}{2(C^2+D^2)}

   円が接した時点(過去)の t が知りたいので,2つの解の内,t≦0の解をとる。
    
23:46 | 投票する | 投票数(0) | コメント(0)