はじめに
放物線状のアンテナに光線(電磁波)を入射させるとその反射波は必ず放物線の焦点を通る。つまり、その点に電磁波のエネルギーや信号が集中する。このようなモデルは、地面に置いてある凸状の放物面に対して上から球体を落とすことである程度再現することができる。そこで、今回はそのような力学モデルを弾性によるエネルギーロスがない理想的な空間で再現する。具体的には、Pythonを用いて質点の運動方程式と反発係数の式を立てることで、以下のようなシミュレーション動画を作成することを目的とする。
今回は以下のような動画を作成することを目的とする。
フルバージョンは以下のgithubのリンクよりみることができる。
条件設定とアルゴリズム
今回の条件として、$y=x^2$の放物面に対して、$y>x^2$の範囲からボールを放物面に向かって初速度0で投げ下ろすものとする。
まず、ボールは放物面に衝突するまでは重力加速度$g$の等加速直線運動を行う。衝突後は、放物面の接線を基準として入射角と反射角が等しくなるような速度を維持しつつ放物面内側方向($|x|$が小さくなる方向)へ反射する。
このような衝突は、エネルギー保存上では永遠に行うことができる訳だが、シミュレーションなので有限の時間を設定してあげる必要性がある。そこで、ボールの初期座標を$(2,5)$とし、$0\le t\le 10$の範囲でシミュレーションを行うものとする。
プログラム
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import japanize_matplotlib
# アニメを作る初期設定
fig = plt.figure()
ims = []
#重力加速度
g=9.8
#放物線面の広さ
x_0=np.linspace(-3,3,100)
#ボールを落とす座標
x_1=2
y_1=5
#初速度
v_x=0
v_y=0
#加速度
a_x=0
a_y=-g
#時間
t=0
#時間の刻み幅
delta_t=0.01
while(t<10):
im=[]
#ボールが放物面に衝突したら反射する。決して放物面の下に行ってはならない。
if (x_1)**2>y_1:
#放物線の接線ベクトル(1+2j*x_1)を基準平面として反射する。(完全弾性衝突とは、入射角と反射角が等しい反射と同じ現象である)
theta=np.angle((v_x+1j*v_y)/(1+2j*x_1))
v=(((-1-2j*x_1)/abs(-1-2j*x_1))/(np.cos(theta)+1j*np.sin(theta)))*(v_x+1j*v_y)
#反射する方向は、必ずy軸側に向かうようにする。つまり放物線の内部でのみ反射を繰り返すものとする。
if x_1>0:
v_x=-v.real
v_y=v.imag
else:
v_x=v.real
v_y=v.imag
#ボールの速度と位置の更新
v_x=v_x+a_x*delta_t
v_y=v_y+a_y*delta_t
x_1=x_1+v_x*delta_t
y_1=y_1+v_y*delta_t
#放物面の描写
im1=plt.plot(x_0,x_0**2)
#ボールの描写
im2=plt.plot(x_1,y_1,"o",color="red")
ims.append(im1+im2)
#時間の更新
t=t+delta_t
# 複数枚のプロットを 20ms ごとに表示
ani = animation.ArtistAnimation(fig, ims, interval=20)
#保存
ani.save("放物線の焦点.gif", writer="pillow")
これを実行すると以下のようなgifファイルが出力される。
たしかに、ボールの軌跡は放物面の焦点付近を何度も反射により通っていることがわかる。ただし、焦点付近とぼかしたのは、質点であるボールは重力の影響があり、光線のような完全な直進性を持ち得ていないからである。以下は、放物面の焦点に関する分かりやすい記事である。
まとめ
今回は、Pythonを用いて放物面の上空から質点を落下させた場合に、それが描く軌道を描写するプログラムを書いた。具体的には、運動方程式と完全弾性衝突の速度式を用いてアルゴリズムを作成した。その結果、質点の軌跡は確かに焦点付近を通過するということが分かった。このように、Pythonは時間を変数にした力学的シミュレーションもアニメーションとして出力することができるため得意であると考えられる。