為什麼要在球面上算,以及怎麼算
平面上的三圓交會用勾股定理就能解。可是經緯度不是平面座標:一度經線的長度隨緯度改變,兩點之間的「直線」其實是大圓弧。距離一旦超過幾十公里,把地圖當平面會讓三個圓交不到同一點。底下的推導完全在球面上進行,過程中的數字會跟著上方輸入即時更新。
把經緯度換成三維單位向量
把地心當原點、地球半徑當 1。緯度 φ、經度 λ 的一點,在空間中的位置向量是:
x 軸指向本初子午線與赤道的交點,z 軸指向北極。這一步之後,所有計算都只是向量運算,不再有經緯度的扭曲問題。
| 站 | φ (°) | λ (°) | x | y | z |
|---|
把距離換成圓心角
球面上兩點的大圓距離 d,等於地球半徑 R 乘上兩個位置向量的夾角 θ。反過來,已知距離就能得到夾角:
而兩個單位向量的夾角,由內積決定。所以「P 到 A 的距離是 dA」這句話,翻成向量語言就是一條方程式:
在幾何上,滿足 a·p = 常數 的所有 p 構成空間中的一個平面,這個平面切過球面所留下的痕跡,就是以 A 為中心、半徑 dA 的球面小圓。上方球面圖畫的三個圓正是這三個平面與球面的交線。
| 站 | d (km) | θ (rad) | θ (°) | cos θ |
|---|
三個平面交於一點:解線性方程組
三個站各給一條方程式,合起來是一個 3×3 的線性系統。未知數是 p 的三個分量:
三個平面在空間中一般會交於唯一一點,用克拉瑪公式(Cramer's rule)就能解出:
其中 Mx 是把 M 的第一行換成右邊那個 cos 向量,其餘類推。這一步不需要平面近似,也不需要迭代,是純代數的封閉解。
目前的數值:det M = —,解得 p = —。
檢查 |p| 是否為 1,把解投影回球面
三個平面的交點不一定剛好落在球面上。如果距離量得完全精確,|p| 會恰好等於 1,表示三個圓真的共點。若距離有誤差,|p| 會偏離 1,這個偏離量就是「三個圓合不攏」的直接指標。
目前 |p| = —。把 p 正規化成單位向量後,它就是球面上最接近三平面交點的位置,當作初始解。
接著用高斯-牛頓法(Gauss–Newton)在球面上微調 p,讓「由 p 反算的三段距離」與「輸入距離」的平方誤差最小:
實作上每次迭代只在 p 的切平面上移動兩個參數(東西向、南北向),再重新正規化回球面,所以永遠不會離開地球表面。距離精確時,這一步幾乎不動;距離有誤差時,它給出最公平的折衷點,而不是偏向某一個站。
把向量換回經緯度
最後一步是 Step 1 的反運算。用 atan2 而不是 arcsin,可以避免象限錯誤:
得到的 φ、λ 就是目標 P 的緯度與經度,也就是上方結果面板的數字。
什麼情況會失敗
- 三個站共線(或很接近共線)。此時 det M 接近 0,三個平面近乎共軸,交點無法確定。實務上三個站最好張成一個夠胖的三角形,把目標包在中間。
- 距離互相矛盾。若 |p| 明顯大於 1(例如 1.05 以上),代表三個圓沒有共同交點,得到的只是「最不矛盾」的位置。結果面板的閉合檢查會標示出來。
- 距離超過半個地球。大圓距離不可能超過 πR ≈ 20015 km,超過就是輸入錯誤。
- 誤差被距離放大。訊號強度換算距離的誤差通常是百分比,站離目標越遠,圓的半徑誤差越大。這和方位角交會「角度誤差隨距離放大」是同一件事的兩種面貌。