Unityで万有引力による運動の確認
高校で習った物理で、式の上では理解していても、実際に確かめたことはないものが多いですよね。そのような物理現象を、Unityの物理エンジンで確かめたらおもしろいのではないかと思い立ちました(物理を習ったのは大昔で、Unityも初心者なので、いろいろ突っ込みどころがあるかもしれません)。
今回は万有引力による運動を確認します。惑星は、太陽と万有引力で引き合うことで、太陽の周りを楕円起動で周回します(ケプラーの法則)。パラメータとC#スクリプトも公開します。
→さらに月の運動を追加した場合はこちら
(ⅰ) 惑星は太陽を1つの焦点とする楕円上を運動する。
(ⅱ) 惑星と太陽とを結ぶ線分が一定時間に通過する面積は一定である。
(ⅲ) 公転周期Tの2乗は、楕円の半長軸aの3乗に比例する(T^2 = ka^3)
万有引力による運動を確認
パラメータは以下の設定としました(スケールはでたらめです)。あとは、C#スクリプト(最後に示す)で惑星に初速と万有引力を与えることで、惑星の動きを再現できました(本当は太陽にも同じ大きさの万有引力がかかりますが、たぶんほとんど影響がないので、ここでは省略)。【A】
万有引力定数G = 6.67E-05 Nm^2/kg^2 (実際の100万分の1)
太陽の質量M = 1E+07 kg
惑星の質量m = 1 kg
太陽と惑星の距離(初期値)r0 = 5 m
惑星の速度(初期値)v0 = 15 m/s (太陽へ向かう方向に対して垂直方向に与える)
ある速度では等速円運動となる
惑星にかかる向心力F(=万有引力)が、
となるとき、惑星は等速円運動をします。
よって、等速円運動となるときの速度vは、向心力 = 万有引力より、
となります。vをこの値に変えてみましょう。【B】
速度が上がり過ぎると無限遠方に飛び去る
力学的エネルギー が、E ≧ 0 なら、無限遠方に飛び去ります。
V について解くと、
が飛び去る条件となります。では、vを17m/sに変えてみましょう。【C】
※視点変えました。
この後しばらく待っても戻ってきませんでした。
[付録] Unityオブジェクト設定とC#スクリプト
今回作成した主なオブジェクトの設定を記載します。
■太陽(Sphere)のコンポーネント設定(記載なしのものはデフォルト)
コンポーネント | 設定 | 備考 | ||||
A | B | C | ||||
Transform | Position | X | 0 m | |||
Y | 0 m | |||||
Z | 0 m | |||||
Rigidbody | Mass | 1E+07 kg | ||||
Use Gravity | チェックなし |
■惑星(Sphere)のコンポーネント設定(記載なしのものはデフォルト)
コンポーネント | 設定 | 備考 | ||||
A | B | C | ||||
Transform | Position | X | 5 m | |||
Y | 0 m | |||||
Z | 0 m | |||||
Rigidbody | Mass | 1 kg | ||||
Use Gravity | チェックなし | |||||
Script | 初速(Z方向) | 15 m/s | 11.55 m/s | 17 m/s | C#スクリプトのStart()で設定する。 | |
力(太陽に向かう方向) | 万有引力を計算して設定 | C#スクリプトのFixed Update()で設定する。 |
万有引力の与え方はこちらが参考になりました。
[Unity] 惑星に向かって物体が落ちるようにする | ftvlog
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlanetBehaviourScript : MonoBehaviour { public GameObject sun; public float initVelocityZ; private float f; //万有引力 private float m; //惑星の質量 private float M; //太陽の質量 private float r; //太陽と惑星の距離 private float G = 6.67E-5f; //万有引力定数(通常の1000000倍) void Start () { //惑星に初速を与える Vector3 initVelocity = new Vector3(0f, 0f, initVelocityZ); ; GetComponent<Rigidbody>().velocity = initVelocity; //惑星と太陽の質量を取得しておく m = GetComponent<Rigidbody>().mass; M = sun.GetComponent<Rigidbody>().mass; } void FixedUpdate() { //惑星から太陽に向かうベクトルを計算 Vector3 direction = sun.transform.position - GetComponent<Transform>().position; //太陽と惑星の距離rを計算 r = direction.magnitude; //単位ベクトルに変換(後で万有引力の方向として使う) direction.Normalize(); //万有引力を計算 f = G * m * M / (r * r); //万有引力を与える GetComponent<Rigidbody>().AddForce(f * direction, ForceMode.Force); } }