計算まちがってたらごめんよー
※経度(度・分)を使いたい場合は右下の「経度による入力」に数値を入れて「from long.」を押します。
※経度を使いたい場合は下の「経度による入力」に数値を入れて「from long.」を押します。
普通、赤経は時分秒であらわす。 一周すると24時。 赤緯は度であらわされている。 一周で360度。 コンピュータでの計算はラジアンを使うことが多い。 一周で \(2\pi\)。 以後、角度については単位を明示的に書かないが、もちろん式の中で統一して計算しなければならない。 三角関数がラジアンを扱うならば、赤経も赤緯もラジアンに変換して計算する必要がある。 分かっていると思うけど念のため。
3次元空間中の点 \(P\) を考え、原点 \(O\) を始点とし、 \(P\) を通る半直線 \(OP\) を考える。 このとき、 \(OP\) とX軸のなす角を \(\lambda\) 、Y軸のなす角を \(\mu\) 、Z軸のなす角を \(\nu\) とし、各余弦を \(L\) ・ \(M\) ・ \(N\) とする。 つまり、 \(L=\cos \lambda\)、\(M=\cos\mu\)、\(N=\cos\nu\) である。 これを方向余弦という。 言ってることは面倒くさいが、実際は案外単純で、中心が原点 \(O\) で半径が1の球面(単位球面)を考えたとき、この球面と半直線 \(OP\) が交わる点の座標が \((L,\ M,\ N)\) である。 つまり、半直線 \(OP\) の単位方向ベクトルになっている。 なぜならば、例えばX軸について考えてみると、X軸と \(OP\) を含む平面を考えれば、この平面上でX軸と \(OP\) の間の角が \(\lambda\) である。 単位球面とこの平面が交わった部分は当然単位円になる。 単位円と半直線 \(OP\) が交わった点のX座標はもちろん \(\cos\lambda\) である。
方向余弦は単位方向ベクトルなので、赤経 \(\alpha\) ・赤緯 \(\delta\) の点Pの方向余弦は、 \(L=\cos\alpha\cos\delta,\ M=\sin\alpha\cos\delta,\ N=\sin\delta\) になる。 単位球面上で赤緯 \(\delta\) の点の集合は円になるが、この円は \(Z=\sin\delta\) の位置にあり、半径が \(\cos\delta\) である。 したがって、この円周上の赤経 \(\delta\) の点のX座標は \(\cos\alpha\cos\delta\) で、Y座標は \(\sin\alpha\cos\delta\) になる。 この変換では、X軸の正の方向が春分点を、Z軸の正の方向が天の北極を向いており、Y軸の正の方向は赤道上の赤経6hの方向を向くことになる。
上記の反対をやればよい。
方向余弦
\((L,\ M,\ N)\)
が与えられたら、
\(N=\sin\delta\)
となるような
\(\delta\)
が赤緯になる。
赤経は
\((L,\ M)\)
の偏角になるので
\(M/L=\tan\alpha\)
となるようなαになるのだが、普通にarctanを使うと赤経の範囲が-6hから+6hになってしまう。
この場合は
\(L\)
の符号を見て、
\(L\)
がマイナスならば赤経に12hを足してあげよう。
最終的に結果がマイナスだった場合は24hを足してあげよう。
\(L\)
が0の場合は
\(M/L\)
が計算できない。
これをチェックしないとプログラムがコケる原因になる。
\(L=0\)
かつ
\(M=0\)
というパターン(
\(N=\pm 1\)
の場合、つまり、赤緯±90度の場合)もあるので注意。
atan2(y, x)
があるならこちらを使ったほうが楽。
赤道座標で二つの点 \(P\) ・ \(Q\) が与えられたとき、原点 \(O\) を始点とした半直線 \(OP\) と \(OQ\) のなす角 \(\theta\) が角距離、あるいは離角である。 \(P\) も \(Q\) も赤道上にあれば赤経の差になり、同じ子午線上にあれば赤緯の差になるが、それ以外の場合は単純には計算できない。 \(OP\) と \(OQ\) の方向余弦を求めれば、これはつまり単位方向ベクトルなので、両者の内積が \(\cos\theta\) になることから求める。
ふたつの3次元ベクトル \((x_1,\ y_1,\ z_1)\) と \((x_2,\ y_2,\ z_2)\) の内積は
\(x_1\cdot x_2+y_1\cdot y_2+z_1\cdot z_2\)
なので、\(P\)・\(Q\) の方向余弦さえ分かれば簡単に計算できる。 \(P\) の赤経が \(\alpha\) 、赤緯が \(\delta\) 、\(Q\) の赤経が \(\beta\) 、赤緯が \(\epsilon\) だとすると、\(P\) の方向余弦は
\((\cos\alpha\cos\delta,\ \sin\alpha\cos\delta,\ \sin\delta)\)
\(Q\) の方向余弦は
\((\cos\beta\cos\epsilon,\ \sin\beta\cos\epsilon,\ \sin\epsilon)\)
なので、内積は
\(\cos\alpha\cos\delta\cos\beta\cos\epsilon + \sin\alpha\cos\delta\sin\beta\cos\epsilon + \sin\delta\sin\epsilon\)
となり、前2項を \(\cos\delta \cos\epsilon\) でくくって、
\(\cos\delta\cos\epsilon(\cos\alpha\cos\beta + \sin\alpha\sin\beta) + \sin\delta\sin\epsilon\)
加法定理
\(\cos(\alpha-\beta) = \cos\alpha\cos\beta + \sin\alpha\sin\beta\)
を逆に使うことで、
\(\cos\theta = \cos\delta\cos\epsilon\cos(\alpha-\beta) + \sin\delta\sin\epsilon\)
となることが分かる。
方向余弦に直す → 中点のベクトルを求める → 大きさを1に正規化することで方向余弦に直す → 赤経・赤緯に戻す。
大きさが0になってしまう場合(中点が原点と重なった場合)もあるので注意。
この場合は2点がちょうど正反対の位置にある、ということである。
このプログラムではpoints are too far
と言われる。
投影とは3次元空間内の点を2次元である平面上の点に対応させることで、透視投影とは空間中の点 \(P\) を、視点 \(V\) と \(P\) を結ぶ直線 \(VP\)(視線)と、投影面の交点に対応させる投影のこと。 早い話が普通に写真を撮れば透視投影になる、収差を考えなければ。 我々は天球の中心、つまり原点 \(O\) にいるので、視点 \(V\) は原点 \(O\) の位置になる。
この条件で大円を透視投影すると直線になる。 球面上の線を透視投影した結果が直線になるなら球面上の線は大円になる。 なぜなら、投影面上に直線Lを引き、投影のために原点とこの直線上の点を結ぶと、これらの線分(視線)の集まりは、直線Lと原点を通る平面に載ることが分かる。 この平面は原点を通っているから、原点を中心とする球面とこの平面が交差してできる曲線は大円になる。 逆に大円は原点を通る平面上にあり、この平面と投影面が交わっているならば、交わった部分は当然直線になる。
原点 \(O\) を始点とし、空間中の点 \(P\) を通る半直線 \(OP\) と、撮像面との交点に投影される。 撮像面の各辺は直線なので、天球上では大円になる。 経線は大円なので、撮像面上では直線になる。 特に赤道上では平行になる(等間隔にはならない)。 そのほかの場所では放射状になる。 一方、緯線は赤道を除いて小円なので、赤道のみが直線、他は曲線になる。
春分点の方向(X軸の正方向)を向いていると、縦辺は経線に平行となるので、横方向の画角が分かれば縦辺の赤経はすぐに分かる。 しかし、横辺は緯線とは並行にならないので、縦方向の画角が分かっただけでは横辺の赤緯は計算できない。
春分点の方向へ向いている場合、撮像面はX軸と垂直な平面上にある。 実際の撮像面の大きさを使い、原点からX軸の正方向に焦点距離だけ離れた位置に置くと分かりやすい。 撮像面上にある点 \(P\) を、撮像面中心を基準として縦方向(南北方向)の位置u、横方向(東西方向)の位置 \(v\) で表す。 焦点距離を \(f\) とすると、点 \(P\) の位置ベクトル、言い換えれば原点からの方向ベクトルは簡単に \((f,\ u,\ v)\) と分かる。 これをベクトルの大きさで割れば方向余弦になる。
撮像面上で \((u,\ v)\) を通り、縦辺と平行な直線は赤経 \(\phi=\tan^{-1}(u/f)\) の経線になる。 横辺と平行な直線は、赤経0、赤緯 \(\psi=\tan^{-1}(v/f)\) を通る大円になる。これは緯線とは異なることに注意。 逆に、 \(\phi\) と \(\psi\) が分かっている場合、焦点距離 \(f\) を適当に仮定して、 \(u=f\cdot\tan\phi,\ v=f\cdot\tan\psi\) となるから、方向ベクトルは \((f,\ f\cdot\tan\phi,\ f\cdot\tan\psi)\) である。 このベクトルの大きさは
なので、
\(k = \sqrt{1 + \tan^2\phi + \tan^2\psi}\)
とおけば、 \(r = fk\) であり、
となって、撮像面の画角だけ分かれば、焦点距離がなくても方向余弦を求められる。
撮像面として視線に垂直な面を考え、撮像面上の \((u,\ v)\) 座標を \((x,\ y,\ z)\) 座標系に変換して、そこから方向余弦を求めてもよいが、面倒なので春分点の方向を向いた状態で計算し、適当に回転したほうが楽。
撮像面中心を赤経を変えずに赤緯δだけ動かす場合、撮像面中心を経線に沿って動かす必要がある。 回転軸は原点 \(O\) を通り、この経線に垂直な直線になるが、これは座標軸と一致しているとは限らない。 一方、撮像面中心を赤緯を変えずに赤経 \(\alpha\) だけ動かす場合、撮像面中心を緯線に沿って動かす。 回転軸は原点 \(O\) を通り、この緯線に垂直な直線になるが、緯線は小円だからこれは常にZ軸である。 回転はX・Y・Z軸のまわりに回転しないと面倒なので、赤経 \(\alpha\)、赤緯 \(\delta\) の方向を向いている場合、先にY軸のまわりに \(\delta\) だけ回転し、さらにZ軸のまわりに \(\alpha\) だけ回転すればよい。
撮像面上 \((u,\ v)\) にある点 \(P\) について、春分点の方向を向いた場合の方向余弦 \((L,\ M,\ N)\) を求め、Y軸周りに \(\delta\) だけ回転すると小円に沿って回る。 これに対して経線は大円なので、赤経は \(\phi\) から動き、赤緯も \(\phi+\delta\) になるとは限らない。 次にZ軸のまわりに \(\alpha\) だけ回転すると、やはり \(P\) は小円に沿って回るが、これは緯線の上を動くことになるので、単純に赤経が \(\alpha\) だけ増える。 つまり、Z軸周りの回転はまじめに計算する必要はなくて、赤道座標に戻してから単に赤経に \(\alpha\) を足せばよい。
方向余弦 \((L,\ M,\ N)\) をY軸まわりにδだけ回転するには、赤緯が増える方向を回転の正方向とすれば、
になる。
09 Oct 2024: 誤記修正
29 Sep 2024: 書式変更、MathJax化
ご意見・ご要望の送り先は あかもず仮店舗 の末尾をご覧ください。
Copyright (C) 1998-2024 akamoz.jp