Up

ケプラーの法則のシミュレーション

 

ケプラーの第1法則と第2法則に基づいたシミュレーションを試みた。スクリプトはリストに示した。

 

図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

 

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

 

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の終了

 

 

 

Home