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;
}
		

円と線との当たり判定のサンプル

最後にサンプルです。
線をドラッグすると、動かすことができます。

このエントリーをはてなブックマークに追加