6.線と円との当たり判定
円と線との当たり判定のやり方を見ていきます。
まず、一時間かけて作った図をご覧ください。
図で見るとわかりやすいですが、対象の線をlとしたとき、そのlと円の中心へ直角になる線が最短距離となります。
その交点との距離と円の半径を比較し、その交点との距離が円の半径以下であれば、当たり判定があることがわかります。
つまりは、この交点と円の中心とのベクトルを求めればいいことになります。
これを射影ベクトルを利用して求めてみます。
まずは、lcベクトルを求めます。
単純に差分で求めます
var lc = subtractVector(this.Center,line.base);
続いて、射影ベクトルpを求めます。
射影ベクトルについては、こちらをご覧ください。
// line.directionは線lのベクトルを表します
var project = projectVector(lc,line.direction);
射影ベクトルが取得できたので、線lと円との最短距離の交点を求めます。
その交点と円の当たり判定が線と円の当たり判定とイコールになっていることがわかると思います。
var nearest = getAddVector(line.base,project);
では、全体の関数を見ていきましょう
/**
* chapter6
* 線と円との当たり判定
*/
cCircle.prototype.CollisionLine = function(line){
var lc = subtractVector(this.Center,line.base);
var project = projectVector(lc,line.direction);
var nearest = getAddVector(line.base,project);
// 円と線と最短距離の点がぶつかっていたら当たっている
return this.CollisionWithPoint(nearest);
}
/**
* chapter6
* 円と点との当たり判定
*
*/
cCircle.prototype.CollisionWithPoint = function(point){
var distance = subtractVector(this.Center,point);
return getVectorLength2D(distance) <= this.Radius;
}
/**
* chapter6
* 正射影ベクトル
*/
function projectVector(project,onto){
// 内積を使って長さを求める
var d = dotProduct2D(onto,onto);
if(0 < d){
var dp = dotProduct2D(project,onto);
return multiplyVector(onto,dp / d);
}
return onto;
}
円と線との当たり判定のサンプル
最後にサンプルです。
線をドラッグすると、動かすことができます。