作問の備忘録

テスト問題を作るときの、大した計算ではないけれども、やろうと思うとめんどくさいことどもを記録。

half-versineの定理

yahoo知恵袋で回答した内容をもう一度まとめる。

 

これは球面三角法における定理で、航海をするときの技術だった。

versineとは、 1-\cos\thetaのことで、和算においては矢と呼ばれた。

half-versineは、これの半分 \frac{1-\cos\theta}{2}で、

つまり \sin^2\frac{\theta}{2}のことである。

あえて日本語にするなら半矢だろうか。弓道と紛らわしいが。

 

球面上の2点A,Bに対し、2点を通る大円上での距離を求めたい。

分かっているものは,2地点の緯度、経度、球の半径rである。

大円上の弧ABに対する中心角を \thetaとすると、 \theta = \frac{d}{r}とおける。

ここから \thetaに対するhalf-versineを球面三角法における余弦定理を用いて求めることができる。

 

以下、単位球面上で考える。

球面三角形ABCにおいて、3辺AB,CA,ABの長さを a, b, cとする。

これらは弧の長さなので、単位球面上において中心角(ラジアン)と一致する。

ここで、弧ABを含む大円と弧ACを含む大円がなす角を \alphaとすると、

 \cos(a) =\cos(b)\cos(c)+\sin(b)\sin(c)\cos(\alpha)

 

さて、これをhalf-versineに書き換えると、

 hav\theta=\frac{1-\cos\theta}{2}から、

 \cos\theta=1-2hav\theta

 1-2hav(a)=\{1-2hav(b)\}\{1-2hav(c)\}+\sin(b)\sin(c)\{1-2hav(\alpha)\}

 1-2hav(a)=1-2\{hav(b)+hav(c)\}+4hav(b)hav(c)+\sin(b)\sin(c)-2\sin(b)\sin(c)hav(\alpha)

 -2hav(a)=-2\{hav(b)+hav(c)\}+4hav(b)hav(c)+\sin(b)\sin(c)-2\sin(b)\sin(c)hav(\alpha)

 hav(a)=\{hav(b)+hav(c)\}-\frac{1}{2}\{4hav(b)hav(c)+\sin(b)\sin(c)\}+\sin(b)\sin(c)hav(\alpha)

 hav(a)=\{hav(b)+hav(c)\}-\frac{1}{2}\{(1-\cos(b))(1-\cos(c))+\sin(b)\sin(c)\}+\sin(b)\sin(c)hav(\alpha)

 hav(a)=\{hav(b)+hav(c)\}-\frac{1}{2}\{1-\cos(b)-\cos(c)+\cos(b)\cos(c)+\sin(b)\sin(c)\}+\sin(b)\sin(c)hav(\alpha)

 hav(a)=\{hav(b)+hav(c)\}-\frac{1}{2}\{1-\cos(b)+1-1-\cos(c)+\cos(b)\cos(c)+\sin(b)\sin(c)\}+\sin(b)\sin(c)hav(\alpha)

 hav(a)=\{hav(b)+hav(c)\}-\frac{1}{2}\{1-\cos(b)+1-\cos(c)-1+\cos(b)\cos(c)+\sin(b)\sin(c)\}+\sin(b)\sin(c)hav(\alpha)

 hav(a)=\{hav(b)+hav(c)\}-hav(b)-hav(c)-\frac{1}{2}\{-1+\cos(b)\cos(c)+\sin(b)\sin(c)\}+\sin(b)\sin(c)hav(\alpha)

 hav(a)=\frac{1}{2}\{1-(\cos(b)\cos(c)+\sin(b)\sin(c))\}+\sin(b)\sin(c)hav(\alpha)

 hav(a)=\frac{1}{2}\{1-\cos(b-c)\}+\sin(b)\sin(c)hav(\alpha)

 hav(a)=hav(b-c)+\sin(b)\sin(c)hav(\alpha) 

 

これをさっきの2点A,Bに対応させる。A,Bの緯度をそれぞれ \phi_1,\phi_2,経度を \lambda_1, \lambda_2とすると、

 a=\theta ,b=\frac{\pi}{2}-\phi_2,c=\frac{\pi}{2}-\phi_1 , \alpha=\lambda_2-\lambda_1なので、

 hav(\theta)=hav(\phi_1-\phi_2)+\sin(\frac{\pi}{2}-\phi_2)\sin(\frac{\pi}{2}-\phi_1)hav(\lambda_2-\lambda_1) 

 hav(\theta)=hav(\phi_1-\phi_2)+\cos(\phi_2)\cos(\phi_1)hav(\lambda_2-\lambda_1) 

 hav(\theta)=hav(\phi_2-\phi_1)+\cos(\phi_2)\cos(\phi_1)hav(\lambda_2-\lambda_1) 

つまり、 \cos \thetaの表さえあれば  hav(\theta)が分かり、さらに \thetaが求められるということである。

これが求められれば、 d=r\thetaでAB間の距離が求められる。

 

実際やってみたところ、

東京とスリジャヤワルダナプラコッテとの距離は、

緯度、経度を小数第1位まで、円周率を3.14で雑に計算した場合でも6853km

国土地理院の楕円体仮定の計算で約6858km

十分実用的だ。

 

しかし、ちょっと待て。

そもそも \cos(a) =\cos(b)\cos(c)+\sin(b)\sin(c)\cos(\alpha)から直接求めても良かったんじゃないだろうか。

 \cos(\theta) =\cos(\frac{\pi}{2}-\phi_2)\cos(\frac{\pi}{2}-\phi_1 )+\sin(\frac{\pi}{2}-\phi_2)\sin(\frac{\pi}{2}-\phi_1)\cos(\lambda_2-\lambda_1)

 \cos(\theta) =\sin(\phi_2)\sin(\phi_1 )+\cos(\phi_2)\cos(\phi_1)\cos(\lambda_2-\lambda_1)

ほぼ同じ答えでたわ。

half-versineにこだわる理由とは一体…

求めやすかったんだろうか。

 

wikipediaによると、half-versineを使うことで、それまでの \sin^2\frac{\theta}{2}を使わなくて済むようになったことが大きいらしい。

そもそも、 \cos\thetaの方は、2点間が近すぎると \cos\theta=0.999999などになって使い物にならなかったので、 \cos\thetaより \sin^2\frac{\theta}{2}の方が都合が良かった。