「physics.js」による仮想物理実験室
球体を床面に衝突させよう!〜衝突相互作用の与え方〜

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

はじめに

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

床面との衝突相互作用を与えた運動

 前項「球体に重力を与えよう!」では、一定力として重力を与えた運動のシミュレーション方法を解説しました。 しかしながら、床面に到達した球体は弾むことを期待してしまいますが、予想に反してすり抜けてしまいます。本項では、仮想物理実験室内に登場する3次元オブジェクト同士の衝突を導入する方法を解説します。
 図1は重力で放物運動する球体が床面と衝突したときの運動をシミュレーションした結果です。衝突前後で、球体の最高点(z軸方向の最大値)は同じであることがわかります。これは、球体がもつ力学的エネルギーが衝突前後で変化していないことを意味します。このような力学的エネルギーが保存則する衝突は弾性衝突と呼ばれます。 一方、力学的エネルギー保存則が成り立たない衝突は非弾性衝突と呼ばれます。

(図1)床面と衝突する球体の運動の様子

球体の放物運動
実際の仮想物理実験室はこちら

衝突相互作用の与え方

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

【プログラムソース1】重力の与え方(ball_gravity_floor.html)
////////////////////////////////////////////////////////////////////
// 球オブジェクトの準備
PHYSICS.physLab.ball = new PHYSICS.Sphere({ 〜 省略 〜});
//球オブジェクトを登場
PHYSICS.physLab.objects.push( PHYSICS.physLab.ball );

////////////////////////////////////////////////////////////////////
// 床オブジェクトの準備
PHYSICS.physLab.floor = new PHYSICS.Floor({ 〜 省略 〜 });
//床オブジェクトを登場
PHYSICS.physLab.objects.push( PHYSICS.physLab.floor );

////////////////////////////////////////////////////////////////////
// 相互作用の準備
////////////////////////////////////////////////////////////////////
//重力の設定
PHYSICS.physLab.setInteraction(
	PHYSICS.physLab,
	PHYSICS.physLab.ball,
	PHYSICS.ConstantForce,
	{
		force : new THREE.Vector3( 0, 0, -10 ).multiplyScalar( PHYSICS.physLab.ball.mass )
	}
);
//球体と床面との衝突の設定
PHYSICS.physLab.setInteraction(
	PHYSICS.physLab.floor,  //床面オブジェクト
	PHYSICS.physLab.ball,   //球オブジェクト
	PHYSICS.SolidCollision, //衝突力の定義
	{
		Er : 1.0,     //並進反発係数
	}
);
//仮想物理実験室のスタートメソッドの実行
PHYSICS.physLab.startLab();

反発係数

 衝突関連パラメータのEr反発係数と呼ばれる係数です。反発係数の定義は後述する「物理のはなし3」で紹介しますが、 「1」は弾性衝突(力学的エネルギーが保存)を表し、「1以外」は非弾性衝突(力学的エネルギーが非保存)を表します。「1」よりも小さい値を与えると衝突後の力学的エネルギーが減少し、最高点が衝突前と比較して反発係数の2乗倍となります。 図2は反発係数として0.6を与えたときの結果です。最高点の高さが0.6^2=0.36倍となっていることが確認できます。

(図2)反発係数0.6の場合

反発係数0.6の場合

相互作用の種類(再掲)

「physics.js」では現在次の5つの相互作用が定義されています。今後順番に解説していきます。
■ 一定力(PHYSICS.ConstantForce)
■ 空気抵抗力(PHYSICS.AirResistanceForce)
■ 剛体同士の衝突(PHYSICS.SolidCollision)
■ 線形ばねによる結合(LinearSpringConnection)
■ 2点間距離固定拘束(PHYSICS.FixedDistanceConnection)

また、次の4つも現在導入を準備しています。
■ 剛体棒による結合(PHYSICS.SolidConnection)
■ クーロン相互作用(PHYSICS.CoulombInteraction)
■ 万有引力相互作用(PHYSICS.UniversalGravitation)
■ レナード・ジョーンズポテンシャル(PHYSICS.LennardJonesPotential)

物理学のはなし3:反発係数

 反発係数は衝突対象物の衝突前後の相対速度の大きさの比で定義されます。 衝突する2つ物体の衝突前と衝突後の速度をそれぞれ\mathbf{v}_1, \mathbf{v}_2\mathbf{v^\prime}_1, \mathbf{v^\prime}_2としたときに、反発係数eは次のとおり定義されます。

e \equiv \frac{|\mathbf{v^\prime}_1-\mathbf{v^\prime}_2  |}{ |\mathbf{v}_1-\mathbf{v}_2| }

なお、今回床面は固定されているので、反発係数は

e = \frac{|\mathbf{v^\prime} |}{ |\mathbf{v}| }

となります。先に触れましたが、反発係数が1の衝突は力学的エネルギーが保存する弾性衝突、反発係数が1以外の衝突は力学的エネルギーが保存しない非弾性衝突と呼ばれます。