2013-10-18 48 views
0

我需要找到給定4個緯度/長點和方位的邊界框(如示例圖片所示)。我總是知道軸承排列的兩點(示例中的1和2),所以我將始終知道邊界框的長度。然而,寬度是任意的,點在線上的任何地方(例子中的3和4)。邊界框給定4經緯度和軸承

enter image description here

我首先想到的是,我將不得不計算出點之間的角度(1 & 3,1 & 4,2 & 3,2 & 4),然後用一系列的「法律的餘弦「方程來計算角點。有一種更簡單的方法嗎?這甚至會工作嗎?

回答

1

因此,環顧四周,甚至詢問可能更合適的地點(這裏),我找到了一個解決方案,基於克里斯韋內斯(here)的東西找到交點給定兩點和他們的方向。因此,爲了獲得邊界框的拐角,我只需將上/下和左/右的每個組合(1 & 3,2 & 3,2 & 4),並找到使用已知軸承的交點並相應地進行調整。例如,要找到圖像的右下角,我會計算點1的方向+1和軸承-180的方向點3的交點。

我可以對算法沒有信譽,甚至根據幾何學的工作原理來解釋它,但它在我的測試中起作用。下面是JavaScript版本由克里斯

public static CoordD getIntersection(CoordD point1, double bearing1, CoordD point2, double bearning2) { 
    double lat1 = rad(point1.latitude); double lon1 = rad(point1.longitude); 
    double lat2 = rad(point2.latitude); double lon2 = rad(point2.longitude); 
    double bearing13 = rad(bearing1); double bearing 23 = rad(bearing2); 
    double dLat = lat2 - lat1; double dLon = lon2 - lon1; 

    double dist12 = 2 * Math.asin(Math.sqrt(Math.sin(dLat/2) * Math.sin(dLat/2) + 
     Math.cos(lat1) * Math.cos(lat2) * Math.sin(dLon/2) * Math.sin(dLon/2))); 
    if (dist12 == 0) return null; 

    double bearingA = Math.acos((Math.sin(lat2) - Math.sin(lat1) * Math.cos(dist12))/
     (Math.sin(dist12) * Math.cos(lat1))); 
    double bearingB = Math.acos((Math.sin(lat1) - Math.sin(lat2) * Math.cos(dist12))/
     (Math.sin(dist12) * Math.cos(lat2))); 
    if (Double.isNaN(bearingA)) bearingA = 0; 
    if (Double.isNaN(bearingB)) bearingB = 0; 

    double bearing12, bearing21; 
    if (Math.sin(dLon) > 0) { 
     bearing12 = bearingA; 
     bearing21 = 2 * Math.PI - bearingB; 
    } else { 
     bearing12 = 2 * Math.PI - bearingA; 
     bearing21 = bearingB; 
    } 

    double alpha1 = (bearing13 - bearing12 + Math.PI) % (2 * Math.PI) - Math.PI; // Angle 2-1-3 
    double alpha2 = (bearing21 - bearing23 + Math.PI) % (2 * Math.PI) - Math.PI; // Angle 1-2-3 

    if (Math.sin(alpha1) == 0 && Math.sin(alpha2) == 0) return null; // Infinite intersections 
    if (Math.sin(alpha1) * Math.sin(alpha2) < 0) return null; // Ambiguous intersection 

    // needed? 
    // alpha1 = Math.abs(alpha1); 
    // alpha2 = Math.abs(alpha2); 

    double alpha3 = Math.acos(-Math.cos(alpha1) * Math.cos(alpha2) + 
     Math.sin(alpha1) * Math.sin(alpha2) * Math.cos(dist12)); 
    double dist13 = Math.atan2(Math.sin(dist12) * Math.sin(alpha1) * Math.sin(alpha2), 
     Math.cos(alpha2) + Math.cos(alpha1) * Math.cos(alpha3)); 

    double lat3 = Math.asin(Math.sin(lat1) * Math.cos(dist13) + 
     Math.cos(lat1) * Math.sin(dist13) * Math.cos(bearing13)); 

    double dLon13 = Math.atan2(Math.sin(bearing13) * Math.sin(dist13) * Math.cos(lat1), 
     Math.cos(dist13) - Math.sin(lat1) * Math.sin(lat3)); 
    double lon3 = lon1 + dLon3; 
    lon3 = (lon3 + 3 * Math.PI) % (2* Math.PI) - Math.PI // normalize to +/-180 

    return new CoordD(deg(lat3), deg(lon3)); 
} 

rad()deg()提供我的Java翻譯是弧度和度之間轉換隻是輔助功能。 CoordD是一個輔助類,它只包含兩個雙精度值來存儲經緯度點。

+0

感謝您發佈自己的問題的答案。這不是我正在尋找的,因爲我只有第1點和第2點。但是,我根據您的代碼段計算了距離點1和點2的距離X的四個角。 – Jules

+0

我不認爲這個解決方案會給一個旋轉的矩形。如果我錯了,請糾正我。 – Pratham

相關問題