ケプラーの法則のシミュレーション
ケプラーの第1法則と第2法則に基づいたシミュレーションを試みた。スクリプトはリスト1に示した。
図1
ケプラーの第1法則は、次のコード
calc_r = Planet(theta, a, dist_fcs)
result =
so.brentq(calc_r.f_dist, 0, 1000)
によりシミュレートしている。クラス型Planetは、2つの焦点からの距離の和と長軸の長さとの差を求めるもので、次のように宣言さている。
class Planet:
def __init__(self,
theta, # 図1におけるθ
a,
# 図1における2aの1/2
dist_fcs): # 図1における2焦点間の距離
self.theta = theta
self.a = a
self.dist_fcs = dist_fcs
def f_dist(self, r):
"""
楕円の焦点からの距離の和と2aとの差
"""
v =
r + ((r*np.cos(self.theta) - self.dist_fcs)**2 +
((r*np.sin(self.theta))**2)) ** 0.5
return v - 2*self.a
ケプラーの第2法則は、次のコードでシミュレートしている。
theta += 5.0 / result
更新画像の表示は、次のコードにより20msec間隔としている。
while time.perf_counter()
< t0 + 0.02: # Screenの提示間隔の調整
pass
pg.display.flip()
# 提示スクリーンの更新
t0 = time.perf_counter()
これは、使用パソコンの画像の表示レートが60Hzであることによる。
実行中は、次のコードにより、イベントの管理を行っている。
for e in
pg.event.get():
# イベントの取得
if
e.type == pg.QUIT:
# Windowのクローズボンタが押されたか
ck = False
elif
e.type == pg.KEYDOWN:
# 押されたキーがあるか
if e.key == pg.K_ESCAPE:
# 押されたキーはESCキーか
ck = False
Window画面の右上のcloseアイコンをクリックするか、ESCキーを押すと、スクリプトの実行終了となる。
スクリプトを実行すると、図2のような画面が表示され、小さい点が大きい方の円の周りを回転する。
図2
参考文献
Matthes, E. (2019) Python crash course: A hands-on , project-based introduction to programming. no starch press.
Shankar, R. (2019) Funcdamentals of physics I: Mechanics, relativity, and thermodynamics, expanded edition. Yale University.
リスト1 圧縮ファイルsimuKeplerfile.zipにまとめている。
"""
Simulation on Kepler's laws
"""
import pygame as pg
import time
import numpy as np
import scipy.optimize as so
def __init__(self,
theta, # 図1におけるθ
a,
# 図1における2aの1/2
dist_fcs): # 図1における2焦点間の距離
self.theta = theta
self.a = a
self.dist_fcs = dist_fcs
def f_dist(self, r):
"""
楕円の焦点からの距離の和と2aとの差
"""
v =
r + ((r*np.cos(self.theta) - self.dist_fcs)**2 +
((r*np.sin(self.theta))**2)) ** 0.5
return v - 2*self.a
x0 = 300
a = 300
dist_fcs = 400
#
# 初期値
#
theta = np.pi
calc_r = Planet(theta, a, dist_fcs)
result = so.brentq(calc_r.f_dist, 0,
1000)
pg.init()
# pygameの初期化
screen = pg.display.set_mode((1000, 700))
# 描画スクリーンの設定
pg.display.set_caption("Kepler's
law")
ck = True
# while文の制御用
t0 = time.perf_counter()
# t0の初期値
while ck:
screen.fill((0, 50,
100)) # スクリーンを色(r,g,b)で塗り潰す
# 太陽の描画
pg.draw.ellipse(screen,
(255,255,0),
pg.Rect((x0 - 30, 350 - 30), (60, 60)))
# 惑星の描画
pg.draw.ellipse(screen,
(255,255,255),
pg.Rect((x0 + result*np.cos(theta) -5,
350 + result*np.sin(theta) -5),
(10, 10)))
# The second law of
Kepler
theta += 5.0 / result
if theta > 2*np.pi:
theta -= 2*np.pi
# The first law of Keler
calc_r = Planet(theta, a,
dist_fcs)
result =
so.brentq(calc_r.f_dist, 0, 1000)
while time.perf_counter()
< t0 + 0.02: # Screenの提示間隔の調整
pass
pg.display.flip()
# 提示スクリーンの更新
t0 = time.perf_counter()
for e in
pg.event.get():
# イベントの取得
if
e.type == pg.QUIT:
# Windowのクローズボンタが押されたか
ck = False
elif
e.type == pg.KEYDOWN:
# 押されたキーがあるか
if e.key == pg.K_ESCAPE:
# 押されたキーはESCキーか
ck = False
pg.quit() # pygameの終了