マイコン宇宙講座-太陽と惑星の出没時刻計算
日の出、日の入り時刻に加えて惑星の出没時刻を求めます。N-BASICコードをPythonへ書き直すにあたり、最も苦労しました。というのは処理がGOTO文が使われており、GOTO文がないPythonはループ処理を使わず得ませんでした。しかもループは3重になっており、一番内側から一番外側へジャンプするという処理になっており、それをどう実装するか悩みました。結局、フラグで判断して処理しています。GOTO文があるPHPのほうが実装しやすかったのです。こういうときはGOTO文があるとよいのですね。
さて、出没時刻は0.1分まで求めていますが、実際は1分単位で構いません。秒単位まで必要はないと思います。お天気ニュースでも日の出、日の入りは1分単位ですしね。秒単位の観測は地平線近くでは大気による影響が強すぎて計算した時刻にきちんと観測できません。
サブルーチン appear
対象天体の出没時刻と方位角を計算して返します。
※サブルーチンはlib.pyに記述してください。
# 出没時刻および方位角の計算
def appear(jd, lg, la, ra, dc, ds, rd, sg, hd, K):
if ds > 0:
pp = math.atan(4.26e-5 / ds)
rd = math.atan(rd / (1.5e+8 * ds))
else:
rd = 0.0
pp = 0.0
rr = 0.0102
cc = -math.tan(dc) * math.tan(la)
ss = math.sqrt(1 - cc * cc)
h0 = math.atan(ss / cc)
if h0 < 0:
h0 = h0 + math.pi
dh = (rr + rd - pp) / (math.cos(la) * math.cos(dc) * math.sin(h0))
r1 = jd + sg
r2 = lg
r3 = siderealtime_date(r1, r2)
s1 = r3
if hd == 0:
s2 = ra - h0 - dh
ta = s2 - s1
if ta < 0:
ta = ta + 2.0 * math.pi
ta = ta / 1.002738
ta = K[3] * ta / 15.0
if ta > 24:
ta = ta - 24.0
return ta, 0
if hd == 1:
s3 = ra + h0 + dh
td = s3 - s1
if td < 0:
td = td + 2.0 * math.pi
td = td / 1.002738
td = K[3] * td / 15.0
if td > 24:
td = td - 24
cc = math.sin(dc) / math.cos(la)
ss = -math.cos(dc) * math.sin(h0)
al = abs(math.atan(ss / cc))
if dc < 0:
al = -al + math.pi
return td, al
メインルーチン m312.py
# m312.py
# マイコン宇宙講座
# 3-12 太陽と惑星の出没時刻計算プログラム
import math
import lib
lg = 139.745 / lib.K[3]
la = 35.654 / lib.K[3]
obs = '東京'
lib.PL[3] = 'Sun'
x = [[0 for i in range(10)] for j in range(4)]
f = [0, 0, 0, 0]
q = [0, 0, 0, 0]
ra = [0 for i in range(10)]
dc = [0 for i in range(10)]
print()
std = input('DATE AND TIME(JST) ? ')
dy, dt = std.split(',')
dy = float(dy)
dt = float(dt)
jd, yy, mm, dd, hh, ms, ss = lib.mjd(dy, dt)
iv = input('計算の間隔 ? ')
pn = input('惑星のナンバー ? ')
iv = float(iv)
pn = int(pn)
ja = jd + 365
print()
print(' %-7s(東経 %7.3f 北緯 %6.3f) での %-7s の出没時刻 (JST)' % (obs, lg * lib.K[3], la * lib.K[3], lib.PL[pn]))
print()
print(' Date 出 没 方位')
print(' --------------------------------------------------------(北からの角度)---')
print(' 年 月 日 時 分 時 分 。')
ha = 0
hd = 0
sg = 0
yz = 0
dz = 0
ta1 = 0
td1 = 0
ta = 0
td = 0
al = 0
mz = 0
# 出没時刻の計算
# L300:
while True:
ty = yy + (mm - 1) / 12 + dd / 365
if hd == 0:
ha = ta1
if hd == 1:
ha = td1
# L400:
while True:
sg = 0
if ha > 15:
sg = -1
t1 = jd + sg + ha / 24.0 - 33281.92334
t1 = t1 * (2.737909288e-5 + 1.260132857e-17 * t1)
t2 = t1 * t1
# L440:
while True:
# EARTH
e, m, p, n, i, a, rd = lib.mean_elements(3, t1, t2)
pe = p
nd = n
ic = i
f, q = lib.eph_const(pe, nd, ic, lib.K)
ec = e
mo = m / (2.0 * math.pi)
mo = 2.0 * math.pi * (mo - int(mo))
ss, cc, ff = lib.kepler(mo, ec)
b = a * math.sqrt(1.0 - e * e)
for n in range(1, 4):
x[n][3] = -1 * (ff * a * f[n] + ss * b * q[n])
# 惑星の平均軌道要素の計算
if pn != 3:
e, m, p, n, i, a, rd = lib.mean_elements(pn, t1, t2)
pe = p
nd = n
ic = i
f, q = lib.eph_const(pe, nd, ic, lib.K)
ec = e
mo = m / (2.0 * math.pi)
mo = 2.0 * math.pi * (mo - int(mo))
ss, cc, ff = lib.kepler(mo, ec)
b = a * math.sqrt(1.0 - e * e)
for n in range(1, 4):
f[n] = a * f[n]
q[n] = b * q[n]
# 惑星の座標の計算
for n in range(1, 4):
x[n][pn] = ff * f[n] + ss * q[n]
for n in range(1, 4):
x[n][pn] = x[n][pn] + x[n][3]
# L900:
# 惑星の赤経・赤緯の計算
cc = x[1][pn]
ss = x[2][pn]
tt = lib.quadrant(ss, cc)
ra[pn] = tt
cc = x[1][pn] / math.cos(ra[pn])
ss = x[3][pn]
dc[pn] = math.atan(ss / cc)
r1 = ra[pn]
d1 = dc[pn]
rax, dcx = lib.precession(r1, d1, ty, 0, 0, lib.K)
ra[pn] = rax
dc[pn] = dcx
ds = math.sqrt(x[1][pn]**2 + x[2][pn]**2 + x[3][pn]**2)
rdx = rd
result = lib.appear(jd, lg, la, rax, dcx, ds, rdx, sg, hd, lib.K)
flags_0 = False
flags_1 = False
flags_2 = False
if hd == 1:
td = result[0]
al = result[1]
if abs(td - ha) < 2.0e-3:
flags_2 = True
else:
ha = td
continue
else:
if hd == 0:
# 出
ta = result[0]
if abs(ta - ha) > 2.0e-3:
ha = ta
flags_1 = True
else:
if hd == 0:
hd = 1
ha = ta
flags_0 = True
if flags_0 or flags_1 or flags_2:
break
# end of L440
if flags_0 or flags_2:
break
# end of L400
if flags_0:
continue
if flags_2:
ta1 = ta
ta = ta + 9
if ta > 24:
ta = ta - 24
td1 = td
td = td + 9
if td > 24:
td = td - 24
h1 = int(ta)
m1 = 60.0 * (ta - h1)
h2 = int(td)
m2 = 60.0 * (td - h2)
al = al * lib.K[3]
yy, mm, dd = lib.jdate(jd, lib.T)
sfmt = ' %2d %2d %4.1f %2d %4.1f %6.1f' % (dd, h1, m1, h2, m2, al)
if yy != yz:
sfmt = ' %4d %2d %2d %2d %4.1f %2d %4.1f %6.1f' % (yy, mm, dd, h1, m1, h2, m2, al)
if mm != mz:
sfmt = ' %2d %2d %2d %4.1f %2d %4.1f %6.1f' % (mm, dd, h1, m1, h2, m2, al)
print(sfmt)
yz = yy
mz = mm
if jd < ja:
jd += iv
ha = 0
hd = 0
else:
break
# end of L300
print(' -------------------------------------------------------------------------')
print()
例題 1981年1月1日9時00分00秒から10日おきの火星の出没時刻を求めてみよう。
DATE AND TIME(JST) ? 19810101,090000 計算の間隔 ? 10 惑星のナンバー ? 4 東京 (東経 139.745 北緯 35.654) での MARS の出没時刻 (JST) Date 出 没 方位 --------------------------------------------------------(北からの角度)--- 年 月 日 時 分 時 分 。 1 1 8 13.1 18 9.6 116.3 11 7 59.8 18 10.6 113.7 21 7 45.0 18 10.3 110.9 31 7 28.6 18 9.9 107.6 2 10 7 11.1 18 9.4 104.1 20 6 52.6 18 8.5 100.4 3 2 6 33.4 18 7.2 96.6 12 6 13.6 18 5.7 92.7 22 5 53.6 18 3.8 88.8 4 1 5 33.4 18 1.6 85.0 11 5 13.5 17 59.3 81.2 21 4 53.8 17 56.7 77.7 5 1 4 34.7 17 54.1 74.3 11 4 16.3 17 51.2 71.2 21 3 58.8 17 48.0 68.4 31 3 42.3 17 44.4 65.9 6 10 3 27.0 17 40.1 63.9 20 3 12.9 17 35.0 62.2 30 3 0.0 17 28.8 61.1 7 10 2 48.4 17 21.4 60.3 20 2 37.8 17 12.4 60.0 30 2 28.1 17 1.8 60.2 8 9 2 19.1 16 49.5 60.8 19 2 10.6 16 35.5 61.8 29 2 2.3 16 19.9 63.1 9 8 1 53.9 16 2.7 64.8 18 1 45.4 15 44.1 66.7 28 1 36.4 15 24.1 68.8 10 8 1 26.9 15 3.0 71.0 18 1 16.8 14 40.9 73.4 28 1 5.9 14 17.9 75.9 11 7 0 54.1 13 54.0 78.4 17 0 41.5 13 29.5 80.9 27 0 27.8 13 4.2 83.3 12 7 0 12.9 12 38.2 85.6 17 23 54.9 12 11.6 87.9 27 23 36.9 11 44.1 89.9 1 6 23 16.8 11 15.7 91.7 -------------------------------------------------------------------------