今までの「小惑星帯」シリーズでは、地球から木星へのホーマン軌道を航行する宇宙船だけを計算していた。
でも、それだけじゃなくて、色々な軌道を航行する宇宙船で計算したいよね。
既に書いたように、一連のプログラムは汎用的な宇宙船の軌道に対して計算できるように作ってある。それを説明しよう。
プログラム中、宇宙船を記述している部分は、$spaceCraft と言うオブジェクトだ。このオブジェクトを作るクラスは、SpaceCraft なんだが、このテンプレートは下記のようになっている。
class SpaceCraft
def initialize()
<< 初期化 >>
end
def getStartEndDateTime()
<< シミュレーション開始時刻と終了時刻 >>
return startDateTime,endDateTime
end
def getXV(t)
<< シミュレーション開始時刻から宇宙船の位置と速度を計算 >>
return x,y,z,v
end
end
$spaceCraft = SpaceCraft.new
このようにオブジェクト $spaceCraft は、たった3つの関数しか必要ない。
一つめの「initialize()」は初期化ルーチンで、もし、何も初期化する必要がなければ、空白でも構わない。
二つめの「getStartEndDateTime()」は、シミュレーションの開始時刻と終了時刻を返す関数だ。開始時刻、終了時刻ともに Ruby の DateTime 形式の変数である。
三つめの「getXV(t)」は、シミレーション時刻 t における宇宙船の位置と速度を返す関数だ。t はRuby の DateTime 形式の変数であり、位置は X,Y,Zの3値で単位は AU、速度は単位 m/s だ。(X軸は2000年の春分の日の太陽方向、Z軸は地球軌道面垂直の北方向だ)
と言っても、具体的じゃないと使い方は良く判らないよね。
と言うことで、宇宙戦艦ヤマトが小惑星帯を突っ切る時のシミュレーションを例にして説明しよう。
まず、ネットで調べると、ヤマトは2199年10月10日に地球を出発し、翌11日に木星に到着している。(細かく言うと、この間に一度月へ行き、その後火星にワープした後、木星に行っているのだが、複雑になるので地球から直接木星に行ったことにして計算している)
と言うことで、シミュレーションの開始時刻は2199年10月10日と終了時刻は2199年10月11日に決定。
次に出発日の地球の位置と、到着日の木星の位置を調べよう。
簡単なプログラムを作ってみた。planet.rbだ。
Keplerian Elements for Approximate Positions of the Major Planets のページにある惑星の軌道データである p_elem_t1.txtとp_elem_t2.txtをダウンロードして同じディレクトリに入れておく。
使い方は簡単で、下記のようにコマンドすると、その日の各惑星の座標が表示される。下は LINUX での例だが、Windows でも動くはずだ。
$ ./planet.rb 2199/10/10
日時:2199-10-10T00:00:00+00:00
水星の座標:0.24981685038202 0.199517885753347 -0.00646163832547683
金星の座標:0.104758635915238 0.712548030132175 0.00410577758340108
地球の座標:0.969811669005803 0.242169528844897 -0.000159629098671379
火星の座標:0.208607999745768 1.5342134756758 0.0271095662169784
木星の座標:4.46690521161679 -2.25921162744416 -0.089720069022941
土星の座標:8.25727296133364 -5.33923031072755 -0.240218385841203
天王星の座標:2.01593671944826 19.0180999921417 0.0440323396842922
海王星の座標:27.8666085210368 10.5986082732312 -0.860653284622775
冥王星の座標:-27.3441244017523 22.564811905219 5.49766045953591
$ ./planet.rb 2199/10/11
日時:2199-10-11T00:00:00+00:00
水星の座標:0.22560894627618 0.221734367880399 -0.00243113800090403
金星の座標:0.0846423315647759 0.715105639376437 0.00530200612400009
地球の座標:0.965221462902767 0.258757577936856 -0.000167272010251388
火星の座標:0.195246255145545 1.53723608777542 0.0274973094274193
木星の座標:4.47021365430111 -2.25211110441074 -0.0898227559121188
土星の座標:8.25999112622408 -5.33456363399447 -0.240407888588168
天王星の座標:2.0120016479658 19.0183314422802 0.0440839994093446
海王星の座標:27.8654712607142 10.6015605792454 -0.860687867932851
冥王星の座標:-27.3453017930669 22.5621221647619 5.49828872449565
これで、出発日の地球の位置と到着日の木星の位置が判った。
後は、その間を結ぶ軌道を作るだけだ。でも、たった一日で地球〜木星を楕円軌道で結べない。あまりにも速くなるので、太陽の引力を振り切ってしまうのだ。
ここでは、最も単純に出発点と到着点を直線で結んで等速直線運動にしてしまう。
具体的には次のようなプログラムになる。
class SpaceCraft
def initialize()
@startDateTime = DateTime.new(2199,10,10,0,0,0)
@x0 = 0.969811669005803
@y0 = 0.242169528844897
@z0 = -0.000159629098671379
@endDateTime = DateTime.new(2199,10,11,0,0,0)
@x1 = 4.47021365430111
@y1 = -2.25211110441074
@z1 = -0.0898227559121188
@vx = (@x1 - @x0) / (@endDateTime - @startDateTime)
@vy = (@y1 - @y0) / (@endDateTime - @startDateTime)
@vz = (@z1 - @z0) / (@endDateTime - @startDateTime)
@v = sqrt(@vx * @vx + @vy * @vy + @vz * @vz) * AU / (24.0 * 3600.0)
end
def getStartEndDateTime()
return @startDateTime,@endDateTime
end
def getXV(t)
x = @x0 + @vx * (t - @startDateTime)
y = @y0 + @vy * (t - @startDateTime)
z = @z0 + @vz * (t - @startDateTime)
return x,y,z,@v
end
end
上記を反映したプログラムはasteroidInterval3Y.rbだ。
計算してみると、最も接近した小惑星は 34.4 万キロ だった。これじゃわざわざ避けて通る必要もないねえ。
ところで、ネットで調べてみると、島大介が操縦して小惑星帯を抜けるシーンは火星〜木星間の小惑星帯じゃなくて、冥王星の外の第10惑星の成れの果てという設定だったんだ。30年も前のことだから、すっかり忘れていた。
まあ、そんな遠いところに小惑星があるか判らないし、あったとしても未だ地球から観測されていないので、火星〜木星間の小惑星帯のシミュレーションで許してもらおう。
訂正:
前に計算したときの「地球〜木星のホーマン軌道」に誤りがあった。出発日と到着日に肝心の地球と木星がその場所にない。
実は、今回の planet.rb を作る時に、以前の計算の時に間違いをしていたのに気が付いた。ユリウス日と修正ユリウス日を誤って使っていたのだ。だから、以前の計算は、「地球〜木星のホーマン軌道」ではなく、「地球と同じ太陽からの距離〜木星と同じ太陽からの距離へのホーマン軌道」と思って欲しい。
お詫びして訂正する。
注意
ブログのコンテンツの内、「告知」など時期よって情報価値が無くなるのは除いてある。また、コンテンツに付いたコメントは書き込み者に著作権があるものと判断し、ここに持ってきていないので、コメントを見るときは、元々のブログコンテンツを参照してもらいたい。
その他、ブログ発表後、コメントなどの内容を反映するなど、内容を変更しているものもあるので、注意してほしい。