
衛星からの可視範囲を示す等距離円を地図上に描く

衛星通信では離れた場所から衛星の中継器を介して交信します。 当然のことながら、交信したいアマチュア局の双方から衛星が同時に見えていなくてはなりません。 そのためには衛星からの可視範囲を知る必要があり、その範囲を地図上に表示することが運用に役立ちます。
CALSAT32のメインフォームでも世界地図に衛星の直下点の位置と衛星から見渡すことができる範囲を円で表示しています。

この円は衛星の直下点を中心とした等距離円です。 経度と緯度を等間隔に表示する地図上では、赤道付近で可視範囲が狭ければゆがみの少ない円で表示されますが、可視範囲が広い場合にはゆがみが大きくなります。 また、極の近くではつぶれた形になります。

衛星からの可視範囲は衛星の高度 Eh と地球の半径 Ea
から決まり、つぎの関係があります。
Xd = arccos(Ea / (Eh + Ea))
ここで、Xdは地球の中心から見た衛星の直下点から可視範囲限界までの角度です。
また、大円距離は
Xd の円弧となるので、Ea * Xd から求めることができます。

地球儀の上であれば、衛星の直下点にコンパスの針を置き、大円距離に相当する位置にぐるっと円を描けば、等距離円を描くことができます。 しかし、経度と緯度を等間隔に表示する地図上では、そのような描き方はできません。 確かに北を方位0度として、たとえば1度間隔で360度の大円距離に当たる地点の経緯度を計算して描くこともできると思います。 しかし、ちょっと考えただけでもやっかいな処理に思えます。
そこで、CALSAT32では地球上の特別な地点に注目しました。 それは北極です! 北極を中心に等距離円を描くことは至って簡単なことで、たとえば5000kmの距離に円を描こうと思えば、大雑把には赤道から極までの距離は1万kmですから、その半分の北緯45度の位置に経度0度から360度まで、ぐるっと描けば良いわけです。 もちろん、このままでは経度と緯度を等間隔に表示する地図上では横一直線になってしまいますが、衛星の直下点の緯度の値を使って座標回転を行います。 このような考え方でプログラミングを行うと
単純な計算で複雑と思えるような等距離円を平面上に描くことができます。

それでは、衛星の直下点の経緯度と衛星の高度をスライダーから与え、衛星からの可視範囲円をフォームに表示するプログラムを使ってみましょう。
Calsat32DrawCircle.zipをダウンロードして、解凍してください。
解凍したフォルダに含まれる"Calsat32DrawCircle.exe"を起動して、
いずれかのスラーダーを動かすとつぎのようなフォームが表示されます。 画面がゴチャゴチャになったら「クリアボタン」を押して、これまでに書かれた可視範囲円を消去できます。

また、"Calsat32DrawCircle.vbp"をクリックすると Visual BASIC
が起動して、つぎのコードを見ることができます。
Private Sub Command1_Click()
Form1.picMap.Cls
End Sub
Private Sub mnuExit_Click()
End
End Sub
Private Sub Slider1_Change()
Call disp
End Sub
Private Sub Slider2_Change()
Call disp
End Sub
Private Sub Slider3_Change()
Call disp
End Sub
Sub disp()
Dim dblEi
As Double, dblEk As Double, dblEh As Double
Dim dblPi As Double, dblRad As Double, dblDeg As Double
Dim dblEa As Double
Dim dblXd As Double
Dim dblArcCosXd As Double
Dim dblHoui As Double, dblHr As Double
Dim dblVi As Double, dblVk As Double, dblTanVi As Double
Dim dblX0 As Double, dblY0 As Double, dblZ0 As Double
Dim dblX1 As Double, dblY1 As Double, dblZ1 As Double
Dim dblXi As Double
Dim dblX2 As Double, dblY2 As Double
'定数の設定
dblPi = 4# * Atn(1#)
dblRad = dblPi / 180#
dblDeg = 180# / dblPi
dblEa = 6377#
'衛星の直下点の緯度をスライダーから読み込み
dblEi = -Val(Form1.Slider2.Value)
Form1.Label2.Caption = Format(dblEi, "##0")
dblEi = dblEi * dblRad
'衛星の直下点の経度をスライダーから読み込み
dblEk = Val(Form1.Slider1.Value)
Form1.Label1.Caption = Format(dblEk, "###0")
dblEk = dblEk * dblRad
'衛星の高度をスライダーから読み込み
dblEh = Val(Form1.Slider3.Value)
Form1.Label7.Caption = Format(dblEh, "###,###km")
'可視地心角度
dblArcCosXd = dblEa / (dblEa + dblEh)
dblXd = -Atn(dblArcCosXd / Sqr(-dblArcCosXd * dblArcCosXd + 1#)) + (dblPi / 2#)
'世界地図に衛星の可視範囲円を描く
For dblHoui = 0# To 360# Step 3#
dblHr = (180# - dblHoui) * dblRad
If dblHr >= 2# * dblPi Then
dblHr = dblHr - 2# * dblPi
End If
dblX0 = Cos(dblHr) * Sin(dblXd)
dblY0 = Sin(dblHr) * Sin(dblXd)
dblZ0 = Cos(dblXd)
dblXi = -(dblPi / 2# - dblEi)
dblX1 = dblX0 * Cos(dblXi) - dblZ0 * Sin(dblXi)
dblY1 = dblY0
dblZ1 = dblX0 * Sin(dblXi) + dblZ0 * Cos(dblXi)
'座標変換後の経度
dblVk = Atn(dblY1 / dblX1)
If dblX1 < 0# Then
dblVk = dblVk + dblPi
End If
If dblVk < 0# Then
dblVk = 2# * dblPi + dblVk
End If
dblVk = (dblVk + dblEk) * dblDeg
If dblVk >= 360# Then
dblVk = dblVk - 360#
End If
'座標変換後の緯度
dblTanVi = dblZ1 / (dblX1 ^ 2# + dblY1 ^ 2#) ^ 0.5
dblVi = Atn(dblTanVi)
dblVi = dblVi * dblDeg
'等距離円を描く
If dblHoui = 0# Then
Form1.picMap.PSet (dblVk, dblVi), vbRed
GoTo NextHoui
End If
If (dblX2 - dblVk) < -250 Then
dblY2 = (dblY2 + dblVi) / 2#
Form1.picMap.Line (dblX2, dblY2)-(0#, dblY2), vbRed
Form1.picMap.Line (360#, dblY2)-(dblVk, dblVi), vbRed
GoTo NextHoui
End If
If (dblX2 - dblVk) > 250 Then
dblY2 = (dblY2 + dblVi) / 2#
Form1.picMap.Line (dblX2, dblY2)-(360#, dblY2), vbRed
Form1.picMap.Line (0#, dblY2)-(dblVk, dblVi), vbRed
GoTo NextHoui
End If
Form1.picMap.Line (dblX2, dblY2)-(dblVk, dblVi), vbRed
NextHoui:
dblX2 = dblVk
dblY2 = dblVi
Next dblHoui
End Sub
白地図の左と下にあるスライダーで衛星の直下点を設定します。 一番下のスラーダーは衛星の地上からの高さです。 衛星の高さを高くすると可視範囲がどんどん広がります。 また、衛星の直下点の緯度を高くすると可視範囲円がだんだん歪んで、さらには地図上では円が開いてしまいます。 さまざまな設定で、どのように変化するか試してみましょう。
衛星の可視範囲円を描くことは衛星の位置計算とは直接関係ないことですが、衛星の位置計算プログラムには必要な機能です。 実際に使えるプログラムに仕立てるには、衛星位置
の計算に関する部分のほかに、より多くのユーザーインターフェースのためのコードを書かなくてはなりません。
