こんにちは。
今回は「自由落下」の挙動をpythonで計算してみようと思います。
せっかくpythonを始めたので何かシミュレーションしておこうと思いまして、簡単な自由落下の話からがいいかと思いました。
これでシミュレーションのテンプレのようなものを把握しておけば、今後役に立つと思います。
自由落下をシミュレーションするといったとき、物の位置を知りたいので、位置についての計算になります。
では位置$y$を求めるためにはその時間微分(時間変化)であるところの速度$v= \cfrac{dy}{dt}$を、速度$v$を求めるためにその時間微分の加速度$a= \cfrac{dv}{dt} = \cfrac{d^{2}y}{dt^{2}}$を知る必要があります。
というわけで、加速度を求められれば位置が求められそうです。
自由落下では、加速度$a$は重力加速度$g \sim 9.8$なので、$v=at$、$y=vt$と表すことができ、これを処理上で表すと、以下のようになります。図らずも早速、前回のfor文が役に立ちました。
step = 10 #ステップ数 dt = 0.1 #時間間隔 #初期設定 g = 9.8 v = 0 y = 10 t = 0 for i in range(step) : #0-step数の間繰り返す a = -g #加速度 v += a * dt #速度 y += v * dt #位置 t += dt #時間を進める print(x)
これを実行すると、位置$y$の値が10個出てきます。これでほぼ完成したようなものです。
ちなみに、上のコードをより正確に書くならば、$a= \cfrac{dv}{dt}$、$v= \cfrac{dy}{dt}$の関係式から、以下のようになります。
こちらの方がわかりやすいかもしれませんが、変数が増えるのであまりやりたくありませんね。
step = 10 dt = 0.1 g = 9.8 dv = 0 v = 0 dy = 0 y = 10 t = 0 for i in range(step) : a = -g dv = a * dt v += dv dy = v * dt y += dy t += dt print(x)
床で跳ね返るようにするには、以下のコードをfor文内に入れます。
if y <= 0 and v < 0: #xが0以下(床につく)かつvが負(落下中)なら y = 0 #床表面に移動 v *= -0.7 #跳ね返る
それでは、計算した位置$y$をグラフ化してみましょう。
ここで使うのが「matplotlib」というライブラリの中の「pyplot」というモジュールです。
(ちなみに、モジュール自体は自分で任意につくることができるようです。機会があればブログ化したいと思います。)
ライブラリはコードの始めに以下のコードを追加して読み込みます。
from matplotlib import pyplot as plt
as以下で呼び出すときにどう呼ぶかを指定でき、pyplotでもよいですが少し長いのでpltと略して呼び出せるようにします。
pyplotモジュールのplot関数を使うわけですが、これは数値の指定を配列(リスト)で行うので、計算値をリストに入れる必要があります。
では、リストに入れる、ライブラリを読み込む、グラフ化するという処理の追加をしてみます。
from matplotlib import pyplot as plt #ライブラリの読み込み(省略してpltで呼び出せるようにする) step = 1000 dt = 0.01 #リストの作成 t_list = [] y_list = [] #初期設定 g = 9.8 v = 0 y = 100 t = 0 #初期状態をリストに入れる t_list.append(t) y_list.append(y) for i in range(step) : a = -g v += a * dt y += v * dt t += dt if y <= 0 and v < 0: y = 0 v *= -0.7 #計算結果をリストに入れる t_list.append(t) y_list.append(y) plt.plot(t_list, y_list) #ライブラリをつかってy-tグラフをつくる
これを実行すると、以下のようなグラフが描かれます。
グラフを見ると、二次関数的に位置が変化していることがわかります。$y = y_{0} - gt^{2}$と表せることからも予想ができますね。
processingのようにアニメーションにもできるようですが、グラフでとりあえずの挙動がわかったのでよしとしておきます。
というわけで、自由落下を例にpythonで数値計算をしてそれをグラフ化するという手順について述べてみました。
今回は以上で終わりにしたいと思います。また次回。