[matplotlib animation] 83.ロケットで斜方投射

matplotlib

はじめに

matplotlibのFuncAnimationを使用して、斜方投射のアニメーションをロケット画像で表現する方法を解説します。scikit-imageのtransform.rotateを用いて、ロケットが常に進行方向を向くように回転させる技術も紹介します。

コード

解説

モジュールのインポートなど

バージョン

時間の設定

np.arangeを使用して0.05秒間隔で18秒までの時間データを作成します。この結果、配列のサイズは360になります。重力加速度は9.8 m/s²と設定しました。

初期位置と初速度の設定

初期位置を(0,0)として、初速度100で斜め45°(π/4)方向に打ち上げます。この角度での投射における横方向(v_x)と縦方向(v_y)の速度成分をそれぞれ計算します。

位置の変化

x,yで横方向、縦方向の位置の変化をそれぞれ求めます。

角度の計算

np.arctanで2点のなす角度を計算します。図示すると以下のようになります。

scikit-imageのrotate関数に適用するため、データを反転します。これを図示すると以下のようになります。

地面に到着する時間

t0を用いて地面に到着する時間を計算します。また、np.argmin(np.abs(t-t0))関数で地面到着時間のインデックスも求めます。

データのスライス

データの表示

画像の読み込み

plt.imread(image)関数を使って画像ファイルを読み込みます。このアニメーションでは、下記サイトから取得した画像を使用しました。

ロケットのイラスト
いらすとやは季節のイベント・動物・子供などのかわいいイラストが沢山見つかるフリー素材サイトです。

この画像は斜めに傾いたロケットのため、下記記事と同様の方法で画像を回転させ、上向きのロケット画像を読み込みました。

[scikit-image] 87. 画像を回転させる方法(skimage.transform. rotate)
scikit-imageのrotate関数を使った画像回転処理の完全ガイド。角度指定、リサイズ設定、回転中心の調整など基本パラメータの解説から、アンチエイリアシング適用、補間方法の選択まで実践的な使用方法をコード例付きで紹介します。

プロットの表示

画像を OffsetImage(image, zoom=.1) を使って OffsetImage オブジェクトに変換し、AnnotationBbox で座標 (x[0], y[0]+10) に配置します。図面上に表示するために ax.add_artist(annotation) を実行します。

アニメーションで表示

transform.rotateを使用して画像を進行方向に回転させます。回転した画像をOffsetImageで読み込み、annotation.xybox = (x[i],y[i]+10)で画像位置を更新します。

annotation.offsetbox = im_rrを使って、アノテーションの画像を回転済みのものに置き換えます。

FuncAnimationでアニメーションを生成します。フレーム数はt.shape[0]-1、インターバルは20msに設定し、約6秒のアニメーションを作成します。

HTML(ani.to_html5_video())を実行すると、Jupyter NotebookやJupyter Lab上でアニメーションを直接表示できます。

ani.save(‘ファイル名’, writer=”ffmpeg”, dpi=100)コマンドで、アニメーションをMP4形式で保存できます。

コードをダウンロード(.pyファイル)

コードをダウンロード(.ipynbファイル)

まとめ

本記事では、matplotlibのFuncAnimationとscikit-imageのtransform.rotateを活用して、斜方投射するロケットのアニメーションを作成する方法を紹介しました。このテクニックを応用することで、さまざまな物理シミュレーションの可視化が可能になります。Pythonの画像処理・可視化ライブラリを組み合わせることで、より直感的で魅力的なアニメーションが作成できることを示しました。

参考

[matplotlib animation] 1. プロットのマーカーを画像としてアニメーション表示
matplotlibのFuncAnimationとAnnotationBboxでタートルグラフィックスのようなアニメーション。
skimage.transform — skimage 0.26.0rc0.dev0 documentation
matplotlib.offsetbox — Matplotlib 3.1.0 documentation

コメント