マイコン宇宙講座-惑星の連続した動きを描くⅡ

木星から冥王星までの連続した動きを描きます。前記事の「惑星の連続した動きを描くⅠ」と違って短いプロット期間では動きを確認することができません。今回はプロット期間を10年、プロット間隔を1年としました。これで動きを描くことができますが、水星から火星までの動きのプロットがおかしなことになります。本来ならばメインルーチンをひとつで実行を確認できるのですが、あえて2つに分けてあります。前記事の「惑星の連続した動きを描くⅠ」との違いはプロット期間とプロット間隔だけですので、値を変更するだけで済みます。

メインルーチン m33.py

# m33.py
# マイコン宇宙講座
# 3-3 太陽系の惑星位置表示プログラム
# 木星-冥王星の連続した動きを描く
from PIL import Image, ImageDraw, ImageFont
from tkinter.constants import SOLID
import tkinter as tk
import math
import lib


M2PI = 2.0 * math.pi


# 太陽系を表示する
def display_solor_system():
    global photo

    std = editbox.get()
    dy, dt = std.split(',')
    dy = float(dy)
    dt = float(dt)

    jd, yy, mm, dd, hh, ms, ss = lib.mjd(dy, dt)

    drawing_solor_system(jd, yy, mm, dd, lib.T)

    # 保存された画像を表示
    photo = tk.PhotoImage(file='./images/solor.png')
    canvas.create_image(1, 1, image=photo, anchor=tk.NW)

    # テキストボックスの中身をクリア
    editbox.delete(0, tk.END)

    # 日付と時刻の入力欄にフォーカスをセット
    editbox.focus_set()


# 太陽系を描く
def drawing_solor_system(jd, yy, mm, dd, T):
    img = Image.new('RGB', (642, 402), (0, 0, 0))
    draw = ImageDraw.Draw(img)

    # フォント名は実行環境に合わせて変更すること
    # TrueTypeの等幅フォント名を指定する
    font1 = ImageFont.truetype('TakaoGothic.ttf', 16)
    font2 = ImageFont.truetype('TakaoGothic.ttf', 12)

    # 惑星のカラーパレット
    planet_color = [
        '#ff0000',
        '#FFD7A0',
        '#FAAF3C',
        '#37AAE1',
        '#FF5050',
        '#B9BEB4',
        '#C8A05F',
        '#A0C8FA',
        '#3232E1',
        '#E6B96E'
    ]

    # 画面補正値
    pwx = 4
    pwy = 4

    # 画面上の太陽の位置
    mx = 412
    my = 200
    sx = 110
    sy = 110

    # フレームを描く
    draw.rectangle((0, 0, 640, 400))
    draw.line((224, 0, 224, 400))
    draw.line((0, 220, 224, 220))

    # Sun
    draw.ellipse((mx - 4, my - 4, mx + 4, my + 4), fill=(255, 0, 0))  # メイン画面
    draw.ellipse((sx - 4, sy - 4, sx + 4, sy + 4), fill=(255, 0, 0))  # サブ画面

    # 春分点の方向(メイン画面)
    for ln in range(418, 620, 10):
        draw.line((ln, 200, ln + 5, 200))
    draw.line((625, 200, 620, 195))
    draw.line((625, 200, 620, 205))

    # 春分点の方向(サブ画面)
    for ln in range(114, 210, 5):
        draw.line((ln, 110, ln + 2, 110))
    draw.line((214, 110, 209, 105))
    draw.line((214, 110, 209, 115))

    # タイトルの表示
    draw.text((400, 380), 'SOLOR SYSTEM', font=font1)

    # 年月日の表示
    datestr = str('%4d年 %2d月 %2d日' % (yy, mm, dd))
    draw.text((65, 230), datestr, font=font2)

    # 惑星名とシンボルを描画
    draw.text((10, 270), 'P', font=font2)
    draw.text((10, 285), 'L SUN------(   ) MERCURY------(   )', font=font2)
    draw.text((10, 300), 'A VENUS----(   ) EARTH--------(   )', font=font2)
    draw.text((10, 315), 'N MARS-----(   ) JUPITER------(   )', font=font2)
    draw.text((10, 330), 'E SATURN---(   ) URANUS-------(   )', font=font2)
    draw.text((10, 345), 'T NEPTUNE--(   ) PLUTO--------(   )', font=font2)
    draw.text((10, 360), 'S', font=font2)

    # 太陽
    drawing_planet_symbol(0, 91, 291, planet_color[0], draw)
    # 水星
    drawing_planet_symbol(1, 204, 291, planet_color[1], draw)
    # 金星
    drawing_planet_symbol(2, 91, 306, planet_color[2], draw)
    # 地球
    drawing_planet_symbol(3, 204, 306, planet_color[3], draw)
    # 火星
    drawing_planet_symbol(4, 91, 321, planet_color[4], draw)
    # 木星
    drawing_planet_symbol(5, 204, 321, planet_color[5], draw)
    # 土星
    drawing_planet_symbol(6, 91, 336, planet_color[6], draw)
    # 天王星
    drawing_planet_symbol(7, 204, 336, planet_color[7], draw)
    # 海王星
    drawing_planet_symbol(8, 91, 351, planet_color[8], draw)
    # 冥王星
    drawing_planet_symbol(9, 204, 351, planet_color[9], draw)

    # 期間日数
    ja = jd + 3650.0

    while jd < ja:
        # 惑星の位置計算
        t1 = jd - 33281.92334
        t1 = t1 * (2.737909288e-5 + 1.260132857e-17 * t1)
        t2 = t1 * t1

        for pn in range(1, 10):
            e, m, p, n, i, a, rd = lib.mean_elements(pn, t1, t2)
            ec = e
            mo = M2PI * (m / (M2PI) - int(m / (M2PI)))

            ss, cc, ff = lib.kepler(mo, ec)

            b = a * math.sqrt(1 - ec * ec)
            ss = b * ss
            cc = a * ff

            tt = lib.quadrant(ss, cc)

            v = tt
            r = math.sqrt(ss * ss + cc * cc)
            pp = n + p
            vv = v + pp
            r0 = 15
            if pn > 4:
                r0 = 0.9
            rr = r0 * r
            x = rr * math.cos(vv)
            y = rr * math.sin(vv)
            y = -y
            if pn <= 4:
                # 水星-火星はサブ画面へ
                x2 = int((x * pwx) + sx)
                y2 = int((y * pwy) + sy - 4)
            else:
                # 木星-冥王星はメイン画面へ
                x2 = int((x * pwx) + mx)
                y2 = int((y * pwy) + my)

            # 惑星を描く
            draw.rectangle((x2 - 2, y2 - 2, x2 + 2, y2 + 2), fill=planet_color[pn])

        # 期間のステップ日数
        jd += 365.0

    # 年月日を表示
    yy, mm, dd = lib.jdate(jd, lib.T)
    display_date(jd, lib.T, draw, font2)

    # 画像を保存
    # 必ずPNG形式で保存
    img.save('./images/solor.png')


# 惑星のシンボルを描く
def drawing_planet_symbol(p, x, y, color, draw):
    draw.ellipse((x - 4, y - 4, x + 4, y + 4), fill=color)
    if p == 6:
        draw.line((x - 8, y, x + 8, y), fill=color)


# ユリウス日から年月日を返す
def display_date(jd, T, draw, fonts):
    yy, mm, dd = lib.jdate(jd, T)
    # 年月日の表示
    datestr = str('%4d年 %2d月 %2d日' % (yy, mm, dd))
    draw.text((65, 380), datestr, font=fonts)


# メイン
root = tk.Tk()
root.resizable(False, False)
root.geometry('642x440')
root.title('マイコン宇宙講座 - 木星から冥王星の連続した動きを描く')

canvas = tk.Canvas(root, width=640, height=400, bg='black')
canvas.pack(anchor=tk.NW)

label = tk.Label(root, text='DATE AND TIME(JST):')
label.place(x=10, y=410)

editbox = tk.Entry(root, relief=SOLID)
editbox.place(x=155, y=408, width=140, height=24)

button = tk.Button(root, text='表示', width=6, relief=SOLID, cursor='hand1', command=display_solor_system)
button.place(x=480, y=407)

button = tk.Button(root, text='閉じる', width=6, relief=SOLID, cursor='hand1', command=root.destroy)
button.place(x=558, y=407)

# 日付と時刻の入力欄にフォーカスをセット
editbox.focus_set()

root.mainloop()

例題 2000年1月1日9時00分00秒(JST)から80日間の水星から火星までの動きを描いてみよう。

DATE AND TIME(JST)に20000101,090000と入力して、[表示]をクリックすると、10年間の木星から冥王星までの軌道が描かれます。

木星から冥王星までの連続した軌道
木星から冥王星までの連続した軌道