点と直線の距離をプログラムで求める
点と直線の距離をプログラムで求めてみたいと思います。
点と直線の距離の公式
点と直線の距離を求める公式は以下のようになります。
点$(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関数を使って、
点と線との距離を返すサンプルをあげます。
見にくいですが、左上に点があり、左上に線と点との距離が表示されます。
線をドラッグすることにより移動させることができます。