この記事で扱っていること
- 弾性衝突のシミュレーション
を紹介しています。
注意:すべてのエラーを確認しているわけではないので、記事の内容を実装する際には自己責任でお願いします。また、エラー配線は適当な部分があるので適宜修正してください。
以前別の記事で、モンキーハンティングという高校物理でやるような力学の問題をLabVIEWでシミュレートしてみました。
今回はそんなシミュレーションの第二弾で、これまた高校物理で扱う二球の弾性衝突を扱います。
二つの球があり、片方の球が、もう片方の静止している球にぶつかった後のお互いの運動の様子を表現します。運動量保存と運動エネルギーの保存則から導かれる運動ですね。
例によって3Dピクチャとして運動を見てみます。
どんな結果になるか
指定するのは二つの球の半径と密度、および移動する球の速度です。
二つの球が弾性衝突した後の挙動には二つの球の質量が関わります。
プログラムの構造
実装はイベント駆動型のステートマシンで行いました。
以下、各ステートを確認します。
まずは、defineステートです。このステートで、3Dピクチャの「登場人物」をすべて用意します。
3dピクチャ上に球を表現する場合、その球の大きさ(半径)は一番最初に決められる必要があります。そこで、半径などの設定が変わるたびにこのdefineケースが実行させます。2回目以降に実施している場合、一度シーンrefnumを削除し新たに定義するため、リファレンスを閉じる関数を使用しています。
次にeventケースです。イベント駆動型ステートマシンとして、フロントパネルの数値制御器やブール制御器の値が変更された際に他のステートに遷移するための仕組みを用意しています。
次に、moveステートです。シミュレーションが始まってからまずは移動する方の球(便宜上、球Aと呼びます)が静止している球(球B)に近づくように球Aの位置をずらしていきます。
これらの球が衝突するとはどういう状況かを考えると、
球Aの半径+球Bの半径≦球AのX座標の絶対値
という条件が満たされた場合です。
この条件に対するブール値によって、TRUEなら次のcollideステートに遷移します。
Collideステートでは、弾性衝突の考え方から導かれる運動を球Aと球Bがそれぞれ行います。それぞれの球がどういった運動をするのか、物理的な背景を知りたいという方は次のセクションの内容を参考にしてもらえればいいかなと思いますが、細かい式には興味がないという方はとりあえず下の図のブロックダイアグラムを真似てみてください。
ステートを指定する部分で20より大きいかと判断させている部分がありますが、これはこのステートを何回繰り返したらシミュレーションを終了するかを指定する数であり、20である必要はありません。
衝突前はともかく、衝突後の速度の計算では二つの球の質量が重要になります。球の半径と密度が分かっているので質量は計算で出すことができ、2つの球で計算式自体は同じなのでサブVIとしています。
なお、今回のシミュレーションでは衝突前にはある一定速度、衝突後も2球それぞれ一定速度で運動することになるため、一度運動時の速度が求まったら毎ループで速度を計算する必要はありません。
最後にstopステートです。プログラム終了時に実行され、Whileループを停止させます。
フォーミュラノードを使用する場合
衝突後の挙動についてはフォーミュラノードを使用して計算式をそのまま利用しその結果を位置の指定として扱うこともできます。
今回の問題では例えば以下のようなフォーミュラの記述をすることになります。
こちらもまた、毎ループでp_aやp_bは変わらないため、一度計算したら毎ループでフォーミュラノードを使用するのではなく、シフトレジスタ等で回してやればいちいち計算することがなく効率が良くなります。
ただ、毎ループで2球の速度が異なる可能性がある場合には上の図のプログラムのように毎回計算する必要があるので注意します。
2球の衝突後の動作
プログラムの補足として、2球の弾性衝突後の運動の様子を考えてみます(物理の話になるのでよくわからんという人は無理に読む必要はないと思います)。
この記事では、2球の弾性衝突後の運動を3Dピクチャで表す方法を紹介しました。紙の上では動作について2球それぞれの速度はどうなるといったことがわかるものの、これを実際のアニメーションとして表現して見るのはまた違った面白さがあります。参考にしてもらえると嬉しいです。
ここまで読んでいただきありがとうございました。
コメント