0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ニュートンのゆりかごはなぜ「1個入れば1個出る」のか — 2つの保存則をJavaScriptで検証

0
Posted at

机の上でカチカチやってるあの玉、実は衝突力学の本質を全部含んでいるって知ってましたか?

「端の1個を引っ張って離すと、反対側の1個だけ飛び出す」——これ、運動量保存とエネルギー保存が同時に成り立つ唯一の解なんです。しかも、この原理は自動車の衝突安全設計から宇宙機のドッキングまで、現場でガチで使われている。

今回は、この「ニュートンのゆりかご」を数式→実装→数値検証→実務応用まで一気に解説します。最後にはブラウザで動くシミュレーターで実験もできるので、ぜひ手を動かしてみてください。

▶ 今回のシミュレーター: ニュートンのゆりかご シミュレーター(ブラウザで動作・登録不要)


ざっくり本質:なぜ「k個入ればk個出る」のか

まず直感を掴みましょう。5個の球が一直線に並んでいます。端の球を1個引っ張って離すと、反対側から球が1個飛び出す。なぜ2個や3個じゃないのか?

たとえ話で考えると:

  • もし「1個が超高速で飛び出す」とすると、運動量は合うけど運動エネルギーが合わない(エネルギーが大きすぎる)
  • もし「全部がゆっくり動く」とすると、エネルギーは合うけど運動量が合わない(運動量が小さすぎる)
  • 両方を同時に満たせるのは「同じ個数が同じ速さで出る」だけ

一言でまとめる:ニュートンのゆりかごは「運動量保存則」と「運動エネルギー保存則」という2つの制約を同時に満たす、唯一の解を自動的に選んでいる装置なんです。


数式で理解する:2つの保存則が決める世界

運動量保存則

衝突前後で、系全体の運動量は保存されます(外力が働かない限り)。

m_1 v_1 + m_2 v_2 = m_1 v_1' + m_2 v_2'

ここで $m_1, m_2$ は質量、$v_1, v_2$ は衝突前の速度、$v_1', v_2'$ は衝突後の速度です。

反発係数(e)の定義

衝突前後の相対速度の比を反発係数 $e$ と呼びます。

e = \frac{v_2' - v_1'}{v_1 - v_2}
  • $e = 1$:完全弾性衝突(運動エネルギーも保存)
  • $e = 0$:完全非弾性衝突(くっつく)
  • $0 < e < 1$:非弾性衝突(エネルギーが一部失われる)

等質量の場合の衝突後速度

質量がすべて等しい場合($m_1 = m_2 = m$)、衝突後の速度は驚くほどシンプルになります。

運動量保存と反発係数の式を連立すると:

v_1' = \frac{1-e}{2} v_1 + \frac{1+e}{2} v_2
v_2' = \frac{1+e}{2} v_1 + \frac{1-e}{2} v_2

$e = 1$(完全弾性衝突)の場合:

v_1' = v_2, \quad v_2' = v_1

つまり、速度が完全に入れ替わる。動いていた球は止まり、止まっていた球が同じ速度で動き出す。これが「k個入ればk個出る」現象の正体です。


コードで実装する:JavaScriptで再現

ここが最重要パートです。上記の数式を実際のコードに落とし込みます。このコードは、シミュレーターと同じ考え方で書いた最小実装です。

/**
 * ニュートンのゆりかご 衝突計算コア
 * @param {Array} balls - 球の状態配列 [{x, v, m}, ...]
 * @param {number} e - 反発係数 (0〜1)
 * @param {number} dt - 時間刻み (秒)
 */
function updateCollisions(balls, e, dt) {
    const n = balls.length;
    
    // 隣接球同士の衝突をチェック
    for (let i = 0; i < n - 1; i++) {
        const ball1 = balls[i];
        const ball2 = balls[i + 1];
        
        // 球の直径(今回は1.0と仮定)
        const diameter = 1.0;
        
        // 球同士の距離を計算
        const distance = ball2.x - ball1.x;
        
        // 衝突判定:距離が直径より小さい → 接触
        if (distance < diameter) {
            // 相対速度
            const relativeV = ball1.v - ball2.v;
            
            // 接近中のみ衝突処理(すでに離れているならスキップ)
            if (relativeV > 0) {
                // 等質量なので、衝突後速度は式(3)(4)で計算
                const v1After = ((1 - e) / 2) * ball1.v + ((1 + e) / 2) * ball2.v;
                const v2After = ((1 + e) / 2) * ball1.v + ((1 - e) / 2) * ball2.v;
                
                // 速度を更新
                ball1.v = v1After;
                ball2.v = v2After;
                
                // めり込み防止:球を正しい位置に戻す
                const overlap = diameter - distance;
                ball1.x -= overlap / 2;
                ball2.x += overlap / 2;
            }
        }
    }
    
    // 重力による速度更新(振り子の近似:単振動として扱う)
    const g = 9.81; // 重力加速度 [m/s^2]
    const L = 1.0;  // 弦の長さ [m]
    
    for (let i = 0; i < n; i++) {
        const ball = balls[i];
        // 単振動の復元力(微小角近似)
        const theta = Math.asin(ball.x / L);
        const acceleration = -g * Math.sin(theta);
        ball.v += acceleration * dt;
        ball.x += ball.v * dt;
    }
}

// 使用例:5球の初期化
const balls = [
    { x: -2.0, v: 0.0, m: 1.0 },  // 左端の球(引っ張られた状態)
    { x: -1.0, v: 0.0, m: 1.0 },
    { x:  0.0, v: 0.0, m: 1.0 },
    { x:  1.0, v: 0.0, m: 1.0 },
    { x:  2.0, v: 0.0, m: 1.0 }
];

// シミュレーションループ(1ステップ)
const dt = 0.001; // 1ms刻み
updateCollisions(balls, 0.8, dt); // e=0.8で非弾性衝突

このコードのポイント:

  1. 隣接球のみチェック:一直線に並んでいるので、隣同士だけ調べれば十分
  2. 接近中のみ処理:離れていく衝突は無視(二重処理防止)
  3. めり込み補正:数値誤差で球が重ならないように位置を調整
  4. 振り子の復元力:単振動近似で重力の効果を計算

数値例で確かめる:実際に計算してみる

具体的な数値で検証しましょう。5球のニュートンのゆりかごで、左端の球を速度1.0 m/sで衝突させます。

条件設定

  • 球の質量:$m = 0.1 \text{ kg}$(すべて等しい)
  • 反発係数:$e = 1.0$(完全弾性衝突)
  • 左端の球(球1)の初期速度:$v_1 = 1.0 \text{ m/s}$
  • 残りの球(球2〜球5)の初期速度:$v_2 = v_3 = v_4 = v_5 = 0 \text{ m/s}$

衝突1:球1 vs 球2

運動量保存:

0.1 \times 1.0 + 0.1 \times 0 = 0.1 \times v_1' + 0.1 \times v_2'
0.1 = 0.1(v_1' + v_2') \quad \Rightarrow \quad v_1' + v_2' = 1.0

反発係数($e=1.0$):

1.0 = \frac{v_2' - v_1'}{1.0 - 0} \quad \Rightarrow \quad v_2' - v_1' = 1.0

連立して:

v_1' = 0 \text{ m/s}, \quad v_2' = 1.0 \text{ m/s}

球1が止まり、球2が速度1.0 m/sで動き出す。これが「速度の入れ替わり」です。

衝突2:球2 vs 球3

球2が速度1.0 m/sで球3(静止)に衝突。同じ計算で:

v_2' = 0 \text{ m/s}, \quad v_3' = 1.0 \text{ m/s}

最終結果

これが球4→球5と連鎖し、最終的に:

  • 球1〜球4:速度 $0 \text{ m/s}$
  • 球5:速度 $1.0 \text{ m/s}$

運動量の確認:

  • 衝突前:$0.1 \times 1.0 = 0.1 \text{ kg·m/s}$
  • 衝突後:$0.1 \times 1.0 = 0.1 \text{ kg·m/s}$ ✓ 保存

運動エネルギーの確認:

  • 衝突前:$\frac{1}{2} \times 0.1 \times 1.0^2 = 0.05 \text{ J}$
  • 衝突後:$\frac{1}{2} \times 0.1 \times 1.0^2 = 0.05 \text{ J}$ ✓ 保存

完全に一致。これが「1個入れば1個出る」の数学的根拠です。


シミュレーターで遊ぶ:3つの実験

ここからは実際にシミュレーターを開いて試してみましょう。

実験1:反発係数を変えてみる(e=0.8)

操作:反発係数のスライダーを0.8に設定。左端の球を1個引いて離す。

結果:

  • 右端の球は飛び出すが、徐々に振幅が減衰
  • 運動量バーは基準線に張り付いたまま(保存されている)
  • 運動エネルギーバーが衝突ごとに少しずつ下がる

なぜ?
$e=0.8$ だと、衝突ごとに運動エネルギーが失われます。例えば球1と球2の衝突:

v_1' = \frac{1-0.8}{2} \times 1.0 + \frac{1+0.8}{2} \times 0 = 0.1 \text{ m/s}
v_2' = \frac{1+0.8}{2} \times 1.0 + \frac{1-0.8}{2} \times 0 = 0.9 \text{ m/s}

球1が完全には止まらず、少し動いてしまう。これがエネルギー損失の原因です。

実験2:k=2で2個同時に引く

操作:「引き上げる球の数」を2に設定。左端2個を引いて離す。

結果:

  • 右端から2個の球が同時に飛び出す
  • 真ん中の1個はほとんど動かない

なぜ?
2個の球が速度 $v$ で衝突すると、運動量は $2mv$、エネルギーは $mv^2$。これを1個の球で受け止めようとすると、速度 $2v$ で運動量は合うがエネルギーは $2mv^2$ になって合わない。両方を満たせるのは「2個が同じ速度で出る」だけ。

実験3:重力を極端に変える

操作:重力を0.1(通常の約1/100)に設定。球を1個引いて離す。

結果:

  • 球の落下が非常にゆっくり
  • 衝突のタイミングが間延び
  • 衝突後の球の動きもスローモーション

なぜ?
重力が小さいと復元力が弱くなり、振り子の周期が長くなります。単振動の周期は $T = 2\pi\sqrt{L/g}$ なので、$g$ が小さいほど周期が長くなります。


現場でハマるポイント:適用限界と落とし穴

落とし穴1:「eは材質だけで決まる」は誤解

反発係数 $e$ は衝突速度や温度、表面状態でも変わります。例えばゴルフボールとクラブの衝突:

  • 低速(パター):$e \approx 0.5$
  • 高速(ドライバー):$e \approx 0.83$

CAEで衝突解析する際は、$e$ を定数とせず速度依存モデルを使うのが一般的です。

落とし穴2:「重力=0」にすると振り子じゃなくなる

重力を0に設定すると、球は衝突後一直線に等速運動して戻ってこなくなります。これは振り子モデルの破綻です。実務でもパラメータの極端な設定はモデルの適用範囲を超える典型例。

落とし穴3:完全弾性衝突は現実には存在しない

$e=1$ は理想状態。現実の材料では:

  • 鋼球同士:$e \approx 0.95$
  • ガラス玉:$e \approx 0.97$
  • ゴムボール:$e \approx 0.8$

自動車の衝突安全設計では、$e=0.1〜0.3$ の衝撃吸収材を意図的に使ってエネルギーを散逸させます。


まとめ:この1記事で押さえる3つのポイント

  1. ニュートンのゆりかごは「運動量保存」と「エネルギー保存」の可視化装置
    $k$ 個入れば $k$ 個出る——これは2つの保存則を同時に満たす唯一の解

  2. 反発係数 $e$ が現実世界との架け橋
    $e=1$ で完全弾性、$e<1$ で非弾性。実務では $e$ を速度依存でモデル化する

  3. コードで理解すると、物理が「動く」
    たった20行のJavaScriptで衝突計算のコアを実装できる。数式とコードが対応しているから、パラメータを変えたときの挙動が予測できる

もっと深く知りたい方へ:

「カチカチ」が「ガチガチ」になる——そんな体験をしてみてください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?