「physics.js」による仮想物理実験室
球体同士の衝突〜衝突相互作用の与え方2〜

文責:遠藤理平
公開日:2017年03月14日
最終更新日:2017年03月14日

はじめに

 本項物理シミュレーション環境構築用HTML5フレームワーク「physics.js」を用いて物理シミュレーションを行うための手順をチュートリアル形式で紹介する記事です。 最新版「physics.js」(リビジョン14、2017年03月12日現在)をここからダウンロードしてください。以下はチュートリアルの目次です。

運動する球体同士の衝突

 「5.球体を床面に衝突させよう!〜衝突相互作用の与え方〜」で解説したとおり、仮想物理実験室に登場する3次元オブジェクト同士の衝突計算を行うことができます(リビジョン14では球オブジェクトと他のオブジェクトのみ)。 先の項では、静止した床面と球体との衝突でしたが、本項では運動する球体同士の衝突をシミュレーションします。
 図1は回転運動無しの球体オブジェクト同士の衝突のシミュレーション結果です。並進反発係数回転反発係数を「1」と与えているので、力学的エネルギーが保存する弾性衝突となります。

(図1)回転運動無しの球体オブジェクト同士の衝突(弾性衝突)

回転運動無しの球体オブジェクト同士の衝突
実際の仮想物理実験室はこちら

運動する球体同士の衝突相互作用の与え方

 床面の衝突との場合と全く同様に「physics.js」では、登場する3次元オブジェクトへ与える力は全て仮想物理実験室オブジェクト(PhysLabクラス)のsetInteractionメソッドで追加します。第一引数と第ニ引数に相互作用の対象となる3次元オブジェクト、第三引数に相互作用の種類、第四引数にパラメータを指定します。 今回は球体同士の衝突なので、第一引数と第二引数に球体オブジェクトを与え、第三引数には剛体同士の衝突を表すステート定数「PHYSICS.SolidCollision」を、第四引数に衝突関連のパラメータを与えます。

【プログラムソース1】運動する球体同士の衝突(ballsCollision.html)
////////////////////////////////////////////////////////////////////
// 球オブジェクトの準備
PHYSICS.physLab.balls = [];
for( var i = 0; i<2; i++ ){
	PHYSICS.physLab.balls[ i ] = new PHYSICS.Sphere({
		(省略)
		dynamic: true,     //運動の有無
		noRotation : true, //回転運動無し
		(省略)
	});
	//球オブジェクトを登場
	PHYSICS.physLab.objects.push( PHYSICS.physLab.balls[ i ] );
}

//位置と速度との設定
PHYSICS.physLab.balls[ 0 ].position.set(  0, 0, 3);   //位置ベクトル
PHYSICS.physLab.balls[ 0 ].velocity.set(  0, 0, 0);   //速度ベクトル
PHYSICS.physLab.balls[ 0 ].omega.set(     0, 0, 0);   //速度ベクトル
PHYSICS.physLab.balls[ 1 ].position.set( -7, 1.5, 3); //位置ベクトル
PHYSICS.physLab.balls[ 1 ].velocity.set(  5, 0, 0);   //速度ベクトル
PHYSICS.physLab.balls[ 1 ].omega.set(     0, 0, 0);   //速度ベクトル

////////////////////////////////////////////////////////////////////
//相互作用の準備
////////////////////////////////////////////////////////////////////
//球体同士の衝突相互作用
PHYSICS.physLab.setInteraction(
	PHYSICS.physLab.balls[ 0 ],  //球オブジェクト
	PHYSICS.physLab.balls[ 1 ],  //球オブジェクト
	PHYSICS.SolidCollision,      //衝突力の定義
	{
		Er : 1.0,     //並進反発係数
		Et : 1.0,     //回転反発係数
	}
);
//仮想物理実験室のスタートメソッドの実行
PHYSICS.physLab.startLab();

プログラミングメモ

  1. 回転運動無しを指定する場合、noRotationプロパティにfalseを与えます。
  2. 3次元オブジェクトの位置・速度・角速度・姿勢などのパラメータはコンストラクタによる生成時の後でも指定することができます。

回転運動を考慮した球体同士の衝突

 回転運動する球体同士の衝突も同様にシミュレーションすることができます。noRotationプロパティにtrueを与え、角速度をomegaプロパティに与えます。 図2は回転した球体を静止した球体にぶつけた結果です。力学的エネルギーの保存性から計算精度が非常に高く維持できていることがわかります。

(図2)回転運動を考慮した球体オブジェクト同士の衝突(弾性衝突)

回転運動を考慮した球体オブジェクト同士の衝突
実際の仮想物理実験室はこちら

3つの球体の同士衝突

 また3つの球体の同時衝突にも対応しています。図3はその結果です。

(図3)3つの球体の同士衝突(弾性衝突)

回転運動を考慮した球体オブジェクト同士の衝突
実際の仮想物理実験室はこちら

なお、リビジョン14の回転する剛体球の3点以上の同時衝突計算アルゴリズムは不完全なため、詳細は記しませんがある条件をみたす場合には正しい計算結果が得られません。

物理学のはなし6:ニュートンの運動3法則の第三法則「作用・反作用の法則」

 静止した床面に対する球体の衝突の場合、衝突前後の速度を求める条件式は衝突面に対する法線方向の速度の変化のみ(弾性衝突の場合には反転)を考えればよかったのに対して、 運動する球体の同士の場合には、それだけでは条件式が足りません。そこで、ニュートンの運動3法則の最後の一つである「作用・反作用の法則」を課します。 この法則は、2つの球体に加わる力をそれぞれ\mathbf{F}_{12}(1番目の球体に2番目の球体から加えられる力)と\mathbf{F}_{21}(2番目の球体に1番目の球体から加えられる力)と表した場合に、\mathbf{F}_{12}=-\mathbf{F}_{21}が成り立つというシンプルな法則です。この力の関係式を条件式に加えて連立方程式を解くことで、2つの球体に加わる力を計算することができます。なお、球体の数が増えても同じことが言えます。