アトリエ ぺっぺ

トップページ > プログラムTips > 点から線分への垂線の足

◆ 点から線分への垂線の足
任意の点から、任意の線分へ垂直に足をおろした時の交点を求めたい場合があります。
この点は、任意の点から最も近い線分上の点ともいえます。

上図のような場合ですね。そのような場合は、下記のようにします。
bool GetPerpPoint(const Line& line, const Point& pt, POINT& ptPerp)
{
    // 線分が垂直の場合
    if(line.sp.x == line.ep.x){
        
        ptPerp.x = line.sp.x;
        ptPerp.y = pt.y;
    }
    // 線分が水平の場合
    else if(line.sp.y == line.ep.y){

        ptPerp.x = pt.x;
        ptPerp.y = line.sp.y;
    }
    // それ以外
    else{

        double m1, m2, b1, b2;
        // 線分の傾き
        m1 = (line.ep.y - line.sp.y) / (line.ep.x - line.sp.x);
        // 線分のY切片
        b1 = line.sp.y - (m1 * line.sp.x);

        // 点ptを通り、線分lineに垂直な線の傾き
        m2 = -1.0 / m1;
        // 点ptを通り、線分lineに垂直な線のY切片
        b2 = pt.y - (m2 * pt.x);

        // 交点算出
        ptPerp.x = (b2 - b1) / (m1 - m2);
        ptPerp.y = (b2 * m1 - b1 * m2) / (m1 - m2);
    }

    // 線分の範囲内にあるか判定
    if( (   line.sp.x >= ptPerp.x && line.ep.x <= ptPerp.x 
        &&  line.sp.y >= ptPerp.y && line.ep.y <= ptPerp.y
        )
    ||  (   line.ep.x >= ptPerp.x && line.sp.x <= ptPerp.x 
        &&  line.ep.y >= ptPerp.y && line.sp.y <= ptPerp.y
        )
    ){
        return true;
    }
    return false;    
}
	
※ 解説
初めの図を見ると分かりますが、交点を求めるには、「任意の点を通り、任意の線分へ垂直な線」を求め、求めた線と任意の線との交点を求めればよい、ということになります。
線同士の交点は、『線分同士の交点』に書かれている方法で取ることができますが、その前に、任意の線分がX軸と垂直・又は水平の場合は、もっと簡単に交点を知ることができます。
まず、線分がX軸に垂直の場合は下図のようになります。

判定点のX値と任意の線分の始点のY値が、そのまま交点のX値とY値になります。
 
同じように、線分がX軸に水平の場合は下図のようになります。

任意の線分の始点のX値と判定点のY値が、そのまま交点のX値とY値になります。
 
残るのは線が普通に傾いている場合です。
判定点を通り、任意の線分に垂直な線の傾きとY切片(線がY軸に接する時のY値)は、下記のように算出できます。

 
あとは、『線分同士の交点』と同様にして求めています。
 

 

(C) 2002 atelier-peppe
ababa@atelier-peppe.sakura.ne.jp