「physics.js」による仮想物理実験室
球体を回転運動させよう!~角速度の与え方~
はじめに
本項物理シミュレーション環境構築用HTML5フレームワーク「physics.js」を用いて物理シミュレーションを行うための手順をチュートリアル形式で紹介する記事です。 最新版「physics.js」(リビジョン14、2017年04月05日現在)をここからダウンロードしてください。以下はチュートリアルの目次です。
- 1. 仮想物理実験室のつくりかた
- 2. 3次元オブジェクトを配置しよう!
- 3. 球体を運動させてみよう!~運動の有無・位置・速度の与え方~
- 4. 球体に重力を与えよう!~一定力の与え方~
- 5. 球体を床面に衝突させよう!~衝突相互作用の与え方~
- 6. 球体を回転運動させよう!~角速度の与え方~
- 7. 球体に空気抵抗を与えよう~抵抗力の与え方~
- 8. 運動する球体同士の衝突~衝突相互作用の与え方2~
- 9. 球体を単振動運動させよう!~線形ばね相互作用の与え方~
- 10. 球体を単振子運動させよう!~2点間距離固定拘束力の与え方~
- 11. 球体を楕円軌道運動させよう!~万有引力相互作用の与え方~
- 12. 万有引力によるポテンシャルエネルギーの3次元表示モード~ポテンシャルエネルギーの可視化方法~
- 13. 万有引力相互作用で円軌道運動をさせるための初速度の与え方
- 14. クーロン力で点電荷を運動させよう!~クーロン相互作用の与え方~
小技
3次元オブジェクト
- ・Floorクラス(床オブジェクト)
- ・Axisクラス(軸オブジェクト)
- ・Planeクラス(平面オブジェクト)
- ・Circleクラス(円オブジェクト)
- ・Boxクラス(箱オブジェクト)
- ・Cylinderクラス(円柱オブジェクト)
- ・Lineクラス(線オブジェクト)
- ・Pointクラス(点オブジェクト)
- ・Polygonクラス(ポリゴンオブジェクト)
- ・地球オブジェクト(Earthクラス)
- ・Surfaceクラス(曲面オブジェクト)
回転運動させた球体を床面に衝突させた場合
前項「球体を床面に衝突させよう!」では、相互作用として重力+床面との衝突を導入する方法を解説しました。
本項ではじめて回転運動を導入します。図1は回転運動する球体を床面に衝突させた結果です。初期状態として、速度は0としつつ角速度(回転を表すベクトル量)を与えています。並進運動に加え、回転運動を考慮した衝突に対する力学的エネルギー保存則を課してシミュレーションした結果ですが、(自分にとっては)想定外の運動をします。この運動についての考察は後述します。
本シミュレーションでは運動の様子をわかりやすくするための要素を2つ追加しています。1つ目は初期状態の力学的エネルギーからのズレを表す数値テキスト、2つ目は3次元オブジェクトの姿勢をわかりやすくするためのローカル座標系の表示です。実装方法は後述します。
(図1)球体の回転運動+床面との衝突(弾性衝突)
計算誤差について
物理シミュレーションは有限桁しか取り扱うことのできない数値計算によってニュートンの方程式を解くことで実行します。そのため物理シミュレーションには正確な結果からの誤差が必ず含まれるわけですが、その正確性は本来ならば保存する量の変化をモニタリングすることで確かめることができます。
本シミュレーションの場合、力学的エネルギーが保存するはずなので、この量が時間とともにどの程度ずれたかをモニタリングすればよく、画面右上に表示しています。
本シミュレーションでは、力学的エネルギーの変化は10^{-14}程度ですが、JavaScriptの実数(倍精度)の有効桁数は15桁なので、計算誤差はほとんど丸め誤差(有効桁の最後の桁の四捨五入)程度であることがわかります。
角速度の与え方
角速度とは1秒間あたりの回転角度で定義されます。通常、角度の単位は1回転を2πとする弧度法[rad]を用います。また、回転の向きまで含めた量として角速度ベクトルが用いられます。角速度ベクトルの向きを回転軸として、角速度ベクトルの大きさ(絶対値)が角速度に対応します。
physics.jsでは3次元オブジェクトの生成時にomegaプロパティに角速度ベクトルを与えることで回転運動をさせることができます。
【プログラムソース1】角速度の与え方(ball_gravity_floor_rotation.html)
//////////////////////////////////////////////////////////////////// // 球オブジェクトの準備 PHYSICS.physLab.ball = new PHYSICS.Sphere({ (省略) omega: { x: 0, y: 5, z: 0 }, //角速度ベクトル (省略) //ローカル座標系可視化関連パラメータ localAxis : { enabled : true, //ローカル座標系可視化の有無 visible : true, //表示・非表示の指定 size : 2, //軸の長さ dashSize : 0.05, //点線の線の長さ gapSize : 0.05, //点線の空白の長さ colors : [ 0xFF0000, 0x00FF00, 0x0000FF] //軸の配色 } }); //球オブジェクトを登場 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.setInteraction( PHYSICS.physLab.floor, //床面オブジェクト PHYSICS.physLab.ball, //球オブジェクト PHYSICS.SolidCollision, //衝突力の定義 { Er : 1.0, //並進反発係数 Et : 1.0, //回転反発係数 } ); //仮想物理実験室のスタートメソッドの実行 PHYSICS.physLab.startLab();
3次元オブジェクトのローカル座標系に関するプロパティはlocalAxisプロパティにまとめられています。 速度ベクトルや軌跡などと同様、利用する場合にはenabledプロパティをtrueとし、表示と非表示はvisibleプロパティで切り替えることができます。その他にも長さや点線の間隔、線色を指定することができます。
非弾性衝突の場合
図1の弾性衝突の場合との比較として、並進反発係数と回転反発係数をともに0.8と与えたときの結果を以下に示します。10回弱跳ね返った後に、床面上を転がるように進んでいます。
(図2)球体の回転運動+床面との衝突(非弾性衝突)
物理学のはなし4:回転運動を含めた力学的エネルギー保存則
図1のシミュレーションは、回転運動を含めた力学的エネルギー保存則を課した場合の床面との衝突結果ですが、ちょっと想定外でした。このことについて考察します。
1回目の衝突までは回転しながら重力によって下向きに落下します。そして球体は回転の加わった床面との衝突のために推進力を得るところまでは想定通りですが、回転は逆回転になっています。
さらに2回目の衝突時に回転の速さ(角速度)は逆回転から初期状態に戻って、球体はそのまま真上に運動して、初期状態と同じ高さまで戻っています。
反対に考えて、回転運動を含めて周期的な運動をする球体は必ず力学的エネルギー保存則を満たしているはずです。
このように考えれば、球体の回転が1回目の衝突で逆回転にならなければ、1回目の衝突で生まれた並進運動を2回目の衝突で打ち消すことはできないことも理解できます。
ここでは示しませんが、回転を含めた力学的エネルギー保存則を課して導出した計算アルゴリズムは一択です。つまり、重力に対して水平な床面との衝突の場合、「力学的エネルギー保存則」=「周期的運動」が必要十分条件であることが言えることになります。
回転に関する反発係数について
並進運動(回転運動が無い場合)の反発係数は2つの物体の衝突前後の相対速度の比で定義されることは、前項で解説したとおりです。 並進運動に加えて回転運動が存在する場合には、並進運動の反発係数と同様に回転に関する反発係数も定義することができます。 具体的な定義式は示しませんが、physics.jsでは衝突前後の衝突点の速度の比で定義し、回転反発係数と呼ぶことにします。並進運動の反発係数を「1」とした場合、「1」で回転を含めた力学的エネルギー保存則を満たす弾性衝突、「0」で回転に無関係な弾性衝突、それ以外で非弾性衝突となります。