マイコン宇宙講座-楕円軌道表示
離心率を与えて平均近点離角を0°から360°まで変化させながら楕円軌道を表示します。前記事「離心近点離角計算」では数値だけでしたので、なかなかイメージしにくいものでしたが、実際の軌道を表示させるとよく解ると思います。これをベースにして、惑星、小惑星、彗星といった太陽系天体の軌道を表示させたり、ある日の天体の位置を視覚的に表示させることもできます。ただ、これからたくさんの計算が必要ですが、挑戦してみるのもよいと思います。
メインルーチン m29.py
楕円軌道を視覚的に表示しています。Pythonでこれを実現するのにTKinterというグラフィックライブラリを利用しています。また、このプログラムは、「マイコン宇宙講座」のプログラムと基本的な部分は同じであるものの、大部分が異なりますのでコメントをつけてあります。
# m29.py
# マイコン宇宙講座
# 2-9 楕円軌道表示プログラム
from PIL import Image, ImageDraw, ImageFont
from tkinter.constants import SOLID
from tkinter import messagebox as msgbox
import tkinter as tk
import math
import lib
# 「表示」ボタンがクリックされたときの処理
def display_orbit():
global photo # これを忘れると表示されない
std = editbox.get()
if std != '':
ec = float(std)
# 軌道を描く
drawing_orbit(ec)
# 保存された画像を表示
photo = tk.PhotoImage(file='./images/orbit.png')
canvas.create_image(1, 1, image=photo, anchor=tk.NW)
else:
msgbox.showerror('入力エラー', '離心率が入力されていません。')
# 画像を表示したらテキストボックスの中身をクリア
editbox.delete(0, tk.END)
# 離心率editboxにフォーカスをセット
editbox.focus_set()
# 軌道を表示
def drawing_orbit(ec):
img = Image.new('RGB', (640, 400), (0, 0, 0))
draw = ImageDraw.Draw(img)
# フォント名は実行環境に合わせて変更すること
# TrueTypeのフォント名を指定する
fonts = ImageFont.truetype('TakaoGothic.ttf', 13)
a = 44
b = a * math.sqrt(1.0 - ec * ec)
# 太陽を描く
cx = 280
cy = 180
draw.ellipse((cx - 4, cy - 4, cx + 4, cy + 4), fill=(255, 80, 0))
draw.text((cx + 8, cy - 6), 'Sun', font=fonts, fill=(255, 255, 255))
# 軌道を描く
for m in range(0, 360, 5):
mo = m / (180.0 / math.pi)
ss, cc, ff = lib.kepler(mo, ec)
x = -(a * ff) * 4
y = -(b * ss) * 4
x = int(x + cx)
y = int(y + cy)
draw.ellipse((x, y, x + 1, y + 1), fill=(0, 100, 255))
if ec != 0:
a = a / 2.0
q1 = int(a * (1 - ec))
q2 = int(a * (1 + ec))
# 離心率、近日点、遠日点を描画
# 近日点と遠日点の文字位置は実際に描画してみて調整してある
draw.text((5, 5), 'E = ' + str(ec), font=fonts, fill=(255, 255, 255))
draw.text(((35 - 4 - q1) * 8, 11 * 16), 'q', font=fonts, fill=(255, 255, 255))
if ec > 0.8:
xp = 2
else:
xp = 4
draw.text(((35 + xp + q2) * 8, 11 * 16), 'Q', font=fonts, fill=(255, 255, 255))
# 画像を保存
# 必ずPNG形式で保存
img.save('./images/orbit.png')
# メイン
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='離心率(EC):')
label.place(x=10, y=410)
editbox = tk.Entry(root, relief=SOLID)
editbox.place(x=85, y=408, width=100, height=24)
button = tk.Button(root, text='表示', width=6, relief=SOLID, cursor='hand1', command=display_orbit)
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)
# 離心率editoboxにフォーカスをセット
editbox.focus_set()
root.mainloop()
例題 離心率を入力して楕円軌道を表示させてみよう。