Up

2つの物体の運動(2体問題)のシミュレーション

Feynman1963p. 9-6)の方法による

 

質量の2つの物体が引力

で引き合っているときの運動のシミュレーションプログラムを、岡本(1997pp. 139-142の解説に従って作成してみた。

次式

で表される運動方程式を、Feynmanら(1963p. 9-6(第9章の6ページ目)に説明されている方法に基づいて差分で表し、リスト1に示すプログラムを作成した。リスト1のプログラムをNumpyndarray型を用いたものに変更したものは、リストに示した。

プログラムファイルは圧縮ファイルtwomovingobjsfile.zipとしたので、ダウンロード展開すれば自由に利用できる。

リスト1のプログラムでは、差分による更新は以下のようにコーディングされている。ただし、簡単のために

としている。

 

    x0_t = x0 + d_t * vx0h

    y0_t = y0 + d_t * vy0h

    x1_t = x1 + d_t * vx1h

    y1_t = y1 + d_t * vy1h

    r3 = ((x0_t - x1_t)**2 + (y0_t - y1_t)**2) ** (3/2)

    vx0h_t = vx0h + d_t * (-8) * (x0_t - x1_t) / r3

    vy0h_t = vy0h + d_t * (-8) * (y0_t - y1_t) / r3

    vx1h_t = vx1h + d_t * (x0_t - x1_t) / r3

    vy1h_t = vy1h + d_t * (y0_t - y1_t) / r3

 

更新後の2物体の位置は、次のコードにより画面に表示される。

 

    screen.fill((0, 0, 0))

    pg.draw.circle(screen, (255, 200,255), (x_scale(x0), y_scale(y0)), 5)

    pg.draw.circle(screen, (0, 255, 255), (x_scale(x1), y_scale(y1)), 20)

    pg.display.flip()

 

リスト1のプログラムの実行例を、図1に示す。

図1 CentOS Stream 9上で実行

 

実行環境は、Python3.12/Anaconda/CentOS Stream 9である。プログラムを実行すると、画面内で2つの物体(青と黄)の運動が見られるが、表示画面の右上角のX印をクリックするとプログラムの実行終了となる。

 

 

引用文献

Feynman, R. P., Leighton, R. B., & Sands, M. (1963). The Feynman Lectures on Physics, Vol. I. Addison-Wesley Publishing Company.

岡本安晴(1997)Delphiプログラミング入門――Object Pascalの基礎から始める――.CQ出版社

 

 

リスト1 2つの物体の運動のシミュレーション

 

#

#         Simulation of

#       Two Moving Bodies

#

import numpy as np

import pygame as pg

import sys

 

pg.init()

screen = pg.display.set_mode(size=(800,700))

screen.fill((0, 0, 0))

pg.display.flip()

 

def x_scale(x):

    return 400 + x * 100

 

def y_scale(y):

    return 350 + y * 100

#

#       The initial values

#

x0 = 3.0

y0 = 0.0

x1 = 0.0

y1 = 0.0

vx0h = 0.0

vy0h = -0.8

vx1h = 0.0

vy1h = 0.1

 

d_t = 0.001

 

while True:

    #

    #     Calculation of values for update

    #

    x0_t = x0 + d_t * vx0h

    y0_t = y0 + d_t * vy0h

    x1_t = x1 + d_t * vx1h

    y1_t = y1 + d_t * vy1h

    r3 = ((x0_t - x1_t)**2 + (y0_t - y1_t)**2) ** (3/2)

    vx0h_t = vx0h + d_t * (-8) * (x0_t - x1_t) / r3

    vy0h_t = vy0h + d_t * (-8) * (y0_t - y1_t) / r3

    vx1h_t = vx1h + d_t * (x0_t - x1_t) / r3

    vy1h_t = vy1h + d_t * (y0_t - y1_t) / r3

    #

    #        Update the values

    #    cf. Feynman et al. (1963), p. 9-6.

    #

    x0 = x0_t

    y0 = y0_t

    x1 = x1_t

    y1 = y1_t

    vx0h = vx0h_t

    vy0h = vy0h_t

    vx1h = vx1h_t

    vy1h = vy1h_t

    #

    #        Display the updated values

    #       

    screen.fill((0, 0, 0))

    pg.draw.circle(screen, (255, 200,255), (x_scale(x0), y_scale(y0)), 5)

    pg.draw.circle(screen, (0, 255, 255), (x_scale(x1), y_scale(y1)), 20)

    pg.display.flip()

 

    for e in pg.event.get():

        if e.type == pg.QUIT:    #   Is the windows's close button clicked?

            pg.quit()

            sys.exit()

 

    pg.time.wait(1)

 

 

 

リスト2 Numpyndarray型を用いた例

 

#

#         Simulation of

#       Two Moving Bodies

#

import numpy as np

import pygame as pg

import sys

 

pg.init()

screen = pg.display.set_mode(size=(800,700))

screen.fill((0, 0, 0))

pg.display.flip()

 

def x_scale(x):

    return 400 + x * 100

 

def y_scale(y):

    return 350 + y * 100

#

#       The initial values

#

x0 = np.array([3.0, 0.0])

x1 = np.array([0.0,0.0])

v0h = np.array([0.0, -0.8])

v1h = np.array([0.0, 0.1])

 

d_t = 0.001

 

while True:

    #

    #     Calculation of values for update

    #

    x0_t = x0 + d_t * v0h

    x1_t = x1 + d_t * v1h

    r2 = np.sum((x0_t - x1_t)**2)

    v0h_t = v0h + d_t * (-8) * (x0_t - x1_t) / (r2**(3/2))

    v1h_t = v1h + d_t * (x0_t - x1_t) / (r2**(3/2))

    #

    #        Update the values

    #    cf. Feynman et al. (1963), p. 9-6.

    #

    x0 = x0_t

    x1 = x1_t

    v0h = v0h_t

    v1h = v1h_t

    #

    #        Display the updated values

    #       

    screen.fill((0, 0, 0))

    pg.draw.circle(screen, (255, 200,255), (x_scale(x0[0]), y_scale(x0[1])), 5)

    pg.draw.circle(screen, (0, 255, 255), (x_scale(x1[0]), y_scale(x1[1])), 20)

    pg.display.flip()

 

    for e in pg.event.get():

        if e.type == pg.QUIT:    #   Is the windows's close button clicked?

            pg.quit()

            sys.exit()

 

    pg.time.wait(1)

 

 

 

Home