1. 程式人生 > >經緯座標系中求點到線段距離的方法

經緯座標系中求點到線段距離的方法

       在一些地圖的應用中(如求偏航),常常需要求一個點到一條執行緒的距離,以判斷是否遠離航線。然而在經緯度座標中,並沒有類似直角座標系中的公式來計算。在經緯度中,一般應用最廣的公式是求兩點距離的方法,如何通過兩點之間的距離公式來達到計算出點到線段的方法呢,我們先來看在經緯度中求兩點距離的計算方法。

一、經緯度中求兩點距離的計算方法

       網上有很多介紹該計算方法,此處不再 一一闡述。在北半球中:

       C = sin(LatA*Pi/180)*sin(LatB*Pi/180) + cos(LatA*Pi/180)*cos(LatB*Pi/180)*cos((MLonA-MLonB)*Pi/180)

       Distance = R*Arccos(C)*Pi/180

       注1:其中LonA、LatA、LonB、LatB分別是A、B兩個點的經緯度值,其中三角函式的輸入和輸出都採用弧度值

       注2:R(地球半徑)和Distance單位是相同,如果是採用6378.137千米作為半徑,那麼Distance就是千米為單位

      C語言程式碼:

double getDistanceBtwP(double LonA, double LatA,double LonB, double LatB)//根據兩點經緯度計算距離,X經度,Y緯度
{
    double radLng1 = LatA * M_PI / 180.0;
    double radLng2 = LatB * M_PI / 180.0;
    double a = radLng1 - radLng2;
    double b = (LonA - LonB) * M_PI/ 180.0;
    double s = 2 * asin(sqrt(pow(sin(a / 2), 2)+ cos(radLng1) * cos(radLng2) * pow(sin(b / 2), 2))) * 6378.137;	//返回單位為公里
    return s;
}
二、經緯座標中求點到線段的距離的方法

        在經緯座標系中,求點C(LonC,LatC)到以點A(LonA,LatA)和點B(LonB,LatB)為端點的線段的距離D。此問題可以分為三種情況:

       

        ①點C線上段AB的正上方時,則距離D=點C到直線AB的垂直距離,如圖1;

        ②AC與AB形成鈍角時,則距離D=線段AC的長度,如圖2;

        ③BC與AB形成鈍角時,則距離D=線段BC的長度,如圖3;

        1、首先如何判斷是屬於哪種情況

        我們可以利用勾股定理逆定理的推廣,假如AB、BC、AC的長度分別為a,b,c

        ①若b*b+c*c<a*a,則邊a所對的角為鈍角,即圖1的情況;

        ②若a*a+c*c<b*b,則邊b所對的角為鈍角,即圖2的情況;

        ③若a*a+b*b<c*c,則邊c所對的角為鈍角,即圖3的情況;

        2、求圖1情況的距離D

        我們希望可以通過距離公式即可求出距離D,從而聯想到海倫公式。

       在海倫公式中,三角形的面積,其中,則距離D=2S/a;

三、計算方法總結

       對於圖1情況以及計算出,對於圖2和圖3的計算均已轉換為兩個點之間的距離公式,此處不再累贅。因此,在經緯度座標系中,求點到線段的距離的C語言程式碼如下:

//點PCx,PCy到線段PAx,PAy,PBx,PBy的距離
double GetNearestDistance(double PAx, double PAy,double PBx, double PBy,double PCx, double PCy)
{     
	double a,b,c;  
	a=getDistanceBtwP(PAy,PAx,PBy,PBx);//經緯座標系中求兩點的距離公式
	b=getDistanceBtwP(PBy,PBx,PCy,PCx);//經緯座標系中求兩點的距離公式
	c=getDistanceBtwP(PAy,PAx,PCy,PCx);//經緯座標系中求兩點的距離公式
	if(b*b>=c*c+a*a)return c;   
	if(c*c>=b*b+a*a)return b;  
	double l=(a+b+c)/2;     //周長的一半   
	double s=sqrt(l*(l-a)*(l-b)*(l-c));  //海倫公式求面積 
	return 2*s/a;   
}
        第一次發博文,不對之處敬請各位學者提出修改意見,不勝感激!