点と直線の距離をプログラムで求める

点と直線の距離をプログラムで求めてみたいと思います。

点と直線の距離の公式

点と直線の距離を求める公式は以下のようになります。

点$(x_{1},y_{1})$と直線ax + by + c = 0の距離dは

$$d = \frac{|ax_{1} + by_{1} + c|}{\sqrt{a^2 + b^2}}$$

こちらに点と直線の距離の公式の証明についてまとているので、参照してください。

点と直線の距離の公式に当てはめるための準備

点と直線の距離の公式に当てはめるための準備をします。

直線を表す要素として、1点の直線が通る点とその傾きが与えられているものとします。

ここで、直線を表すクラスとしてLineクラスを定義します。

Lineクラスには、以下の要素を持たせて直線を表すことにします。

base その直線が通る2点保持するVector2D
direction 傾きを表すVector2D

ここでは、baseに(100,100)をdirectionに(10,10)(つまり傾き1の直線)を代入して、 Lineクラスを作成します。
Lineクラスの定義は以下の通りです。

	
function Line(){
	// vector2D
	this.base;
	// vector2D
	this.direction
	this.color;
}		
		

点と直線の距離の公式を関数にする

準備が整ったので、点と直線の距離の公式を関数化したいと思います。
返り値に点と直線との距離を引数に先ほど定義したLineクラスとVector2Dと同義Pointクラスを渡す関数を作ります。
手順はコメントに書いておきました


/**
 * 	tips
 *	点と直線の距離を返す
 *
 *	line:Lineクラス
 *	point:Pointクラス
 *
 *	return distance
 */
function getlengthLineBetweenPoint(line,point){
	// 傾きを求める
	// 傾きはlineクラスのdirectionに定義されている
	// (x,y)となるので、y / xが傾きaとなる
	var a = line.direction.y / line.direction.x;
	
	// 続いて切片を求める	
	// 直線の方程式はy = ax + c
	// よって切片はc = y - axとなる
	// lineクラスのbaseにはその直線が通る点が入っている
	var c = line.base.y - (a * line.base.x);
	
	// y = ax + cより y -ax - c = 0
	// となり、ax + by + c = 0の部品が求まる
	var a1 = -a;
	var b1 = 1;
	var c1 = -c;
	
	// 点と直線の距離の公式に当てはめる
	return Math.abs(a1 * point.x + b1 * point.y + c1) / Math.sqrt((a1 * a1) + (b1 * b1));
}
		

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

最後に、作成したgetlengthLineBetweenPoint関数を使って、
点と線との距離を返すサンプルをあげます。
見にくいですが、左上に点があり、左上に線と点との距離が表示されます。
線をドラッグすることにより移動させることができます。