二体問題の解法

二体問題(two-body problem)は、万有引力で相互作用する2つの天体の運動を求める問題です。天体力学の最も基本的な問題であり、解析的に解ける数少ない多体問題のひとつです。ケプラー軌道はこの解として得られます。

本記事の内容

  • 二体問題の定式化
  • 換算質量による1体問題への帰着
  • 軌道方程式 $r = p/(1 + e\cos\nu)$ の導出
  • 比エネルギーと軌道形状の関係
  • Pythonでの数値積分による検証

前提知識

この記事を読む前に、以下の記事を読んでおくと理解が深まります。

二体問題の定式化

質量 $m_1$, $m_2$ の2つの天体が万有引力のみで相互作用するとき、ニュートンの運動方程式は:

$$ m_1 \ddot{\bm{r}}_1 = \frac{Gm_1 m_2}{|\bm{r}_2 – \bm{r}_1|^3}(\bm{r}_2 – \bm{r}_1) $$

$$ m_2 \ddot{\bm{r}}_2 = -\frac{Gm_1 m_2}{|\bm{r}_2 – \bm{r}_1|^3}(\bm{r}_2 – \bm{r}_1) $$

重心座標と相対座標

重心 $\bm{R}$ と相対位置 $\bm{r}$ を定義します:

$$ \bm{R} = \frac{m_1 \bm{r}_1 + m_2 \bm{r}_2}{m_1 + m_2}, \quad \bm{r} = \bm{r}_2 – \bm{r}_1 $$

2式を足すと重心の運動方程式:

$$ (m_1 + m_2)\ddot{\bm{R}} = \bm{0} \implies \bm{R}(t) = \bm{R}_0 + \dot{\bm{R}}_0 t $$

重心は等速直線運動します。

換算質量と相対運動

2式を変形すると、相対運動の方程式が得られます:

$$ \ddot{\bm{r}} = \ddot{\bm{r}}_2 – \ddot{\bm{r}}_1 = -\frac{G(m_1 + m_2)}{r^3}\bm{r} $$

換算質量 $\mu_r$ と重力パラメータ $\mu$ を定義:

$$ \mu_r = \frac{m_1 m_2}{m_1 + m_2}, \quad \mu = G(m_1 + m_2) $$

相対運動の方程式:

$$ \boxed{\ddot{\bm{r}} = -\frac{\mu}{r^3}\bm{r}} $$

二体問題は、質量 $\mu_r$ の仮想的な1つの粒子が中心力場 $\mu$ の下で運動する1体問題に帰着されました。

保存量

角運動量

中心力のためトルクはゼロ:

$$ \bm{h} = \bm{r} \times \dot{\bm{r}} = \text{const} $$

$\bm{h}$ は一定ベクトルなので、運動は $\bm{h}$ に垂直な平面内に限られます。

比力学的エネルギー

$$ \boxed{\varepsilon = \frac{v^2}{2} – \frac{\mu}{r} = \text{const}} $$

軌道方程式の導出

極座標 $(r, \nu)$ を導入します。比角運動量は:

$$ h = r^2 \dot{\nu} $$

$u = 1/r$ と変換し、独立変数を $t$ から $\nu$ に変更します。

$$ \dot{r} = \frac{dr}{dt} = \frac{dr}{d\nu}\dot{\nu} = -h\frac{du}{d\nu} $$

$$ \ddot{r} = -h^2 u^2 \frac{d^2u}{d\nu^2} $$

動径方向の運動方程式 $\ddot{r} – r\dot{\nu}^2 = -\mu/r^2$ に代入:

$$ -h^2 u^2 \frac{d^2u}{d\nu^2} – h^2 u^3 = -\mu u^2 $$

$$ \frac{d^2 u}{d\nu^2} + u = \frac{\mu}{h^2} $$

この2階線形ODEの一般解は:

$$ u = \frac{\mu}{h^2} + A\cos(\nu – \nu_0) $$

$\nu_0 = 0$(近地点方向を基準)とし、$r = 1/u$ に戻すと:

$$ r = \frac{h^2/\mu}{1 + (Ah^2/\mu)\cos\nu} $$

半通径 $p = h^2/\mu$ と離心率 $e = Ah^2/\mu$ を定義して:

$$ \boxed{r = \frac{p}{1 + e\cos\nu} = \frac{a(1-e^2)}{1 + e\cos\nu}} $$

これが軌道方程式(円錐曲線の極座標表示)です。

比エネルギーと軌道形状

軌道方程式をエネルギーで表すと:

$$ \boxed{\varepsilon = -\frac{\mu}{2a}} $$

軌道形状 離心率 $e$ 半長軸 $a$ エネルギー $\varepsilon$
$e = 0$ $a > 0$ $\varepsilon < 0$
楕円 $0 < e < 1$ $a > 0$ $\varepsilon < 0$
放物線 $e = 1$ $a \to \infty$ $\varepsilon = 0$
双曲線 $e > 1$ $a < 0$ $\varepsilon > 0$

Pythonでの実装

import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp

mu = 3.986004418e14  # 地球 [m^3/s^2]
R_earth = 6371e3     # [m]

def two_body_ode(t, state, mu):
    """二体問題の運動方程式"""
    x, y, vx, vy = state
    r = np.sqrt(x**2 + y**2)
    ax = -mu * x / r**3
    ay = -mu * y / r**3
    return [vx, vy, ax, ay]

fig, axes = plt.subplots(2, 2, figsize=(13, 11))

# (a) 軌道方程式: 異なる離心率の軌道
nu = np.linspace(0, 2*np.pi, 1000)
p = 2 * R_earth  # 半通径
for e_val, ls, label in [(0.0, '-', '円 (e=0)'),
                          (0.3, '-', '楕円 (e=0.3)'),
                          (0.7, '-', '楕円 (e=0.7)'),
                          (0.95, '--', '楕円 (e=0.95)')]:
    r_orbit = p / (1 + e_val * np.cos(nu))
    x_orbit = r_orbit * np.cos(nu) / R_earth
    y_orbit = r_orbit * np.sin(nu) / R_earth
    axes[0, 0].plot(x_orbit, y_orbit, ls, linewidth=2, label=label)

# 地球
theta_e = np.linspace(0, 2*np.pi, 100)
axes[0, 0].fill(np.cos(theta_e), np.sin(theta_e), color='cyan', alpha=0.3)
axes[0, 0].plot(0, 0, 'ko', markersize=5)
axes[0, 0].set_xlabel('x / $R_E$')
axes[0, 0].set_ylabel('y / $R_E$')
axes[0, 0].set_title('軌道方程式 $r = p/(1+e\\cos\\nu)$')
axes[0, 0].set_aspect('equal')
axes[0, 0].legend(fontsize=9)
axes[0, 0].grid(True, alpha=0.3)
axes[0, 0].set_xlim(-8, 5)

# (b) 数値解と解析解の比較
a = 2 * R_earth
e = 0.5
r_p = a * (1 - e)
v_p = np.sqrt(mu * (2/r_p - 1/a))
T = 2 * np.pi * np.sqrt(a**3 / mu)

sol = solve_ivp(two_body_ode, [0, T], [r_p, 0, 0, v_p],
                args=(mu,), t_eval=np.linspace(0, T, 1000),
                rtol=1e-12, atol=1e-14)

axes[0, 1].plot(sol.y[0]/R_earth, sol.y[1]/R_earth, 'b-', linewidth=2, label='数値解')
r_analytic = a * (1 - e**2) / (1 + e * np.cos(nu))
x_a = r_analytic * np.cos(nu) / R_earth
y_a = r_analytic * np.sin(nu) / R_earth
axes[0, 1].plot(x_a, y_a, 'r--', linewidth=1, label='解析解')
axes[0, 1].fill(np.cos(theta_e), np.sin(theta_e), color='cyan', alpha=0.3)
axes[0, 1].set_xlabel('x / $R_E$')
axes[0, 1].set_ylabel('y / $R_E$')
axes[0, 1].set_title('数値解 vs 解析解 (e=0.5)')
axes[0, 1].set_aspect('equal')
axes[0, 1].legend()
axes[0, 1].grid(True, alpha=0.3)

# (c) エネルギーと角運動量の保存
r_vals = np.sqrt(sol.y[0]**2 + sol.y[1]**2)
v_vals = np.sqrt(sol.y[2]**2 + sol.y[3]**2)
energy = 0.5 * v_vals**2 - mu / r_vals
h_vals = sol.y[0] * sol.y[3] - sol.y[1] * sol.y[2]

t_norm = sol.t / T
axes[1, 0].plot(t_norm, (energy - energy[0])/np.abs(energy[0]), 'b-', linewidth=1.5,
                label='比エネルギー偏差')
ax_twin = axes[1, 0].twinx()
ax_twin.plot(t_norm, (h_vals - h_vals[0])/np.abs(h_vals[0]), 'r-', linewidth=1.5,
             label='比角運動量偏差')
axes[1, 0].set_xlabel('$t / T$')
axes[1, 0].set_ylabel('エネルギー相対偏差', color='b')
ax_twin.set_ylabel('角運動量相対偏差', color='r')
axes[1, 0].set_title('保存量の数値精度')
axes[1, 0].grid(True, alpha=0.3)

# (d) 放物線・双曲線軌道
nu_open = np.linspace(-2.5, 2.5, 1000)
for e_val, label in [(1.0, '放物線 (e=1.0)'),
                      (1.5, '双曲線 (e=1.5)'),
                      (3.0, '双曲線 (e=3.0)')]:
    r_open = p / (1 + e_val * np.cos(nu_open))
    mask = r_open > 0
    x_open = r_open[mask] * np.cos(nu_open[mask]) / R_earth
    y_open = r_open[mask] * np.sin(nu_open[mask]) / R_earth
    valid = np.abs(x_open) < 15
    axes[1, 1].plot(x_open[valid], y_open[valid], linewidth=2, label=label)

axes[1, 1].fill(np.cos(theta_e), np.sin(theta_e), color='cyan', alpha=0.3)
axes[1, 1].plot(0, 0, 'ko', markersize=5)
axes[1, 1].set_xlabel('x / $R_E$')
axes[1, 1].set_ylabel('y / $R_E$')
axes[1, 1].set_title('放物線・双曲線軌道')
axes[1, 1].set_aspect('equal')
axes[1, 1].legend(fontsize=9)
axes[1, 1].grid(True, alpha=0.3)
axes[1, 1].set_xlim(-12, 8)
axes[1, 1].set_ylim(-10, 10)

plt.tight_layout()
plt.savefig('two_body_problem.png', dpi=150, bbox_inches='tight')
plt.show()

まとめ

本記事では、二体問題の解法について解説しました。

  • 二体問題は換算質量を用いて1体の中心力問題に帰着される
  • 相対運動方程式: $\ddot{\bm{r}} = -\mu\bm{r}/r^3$
  • 軌道方程式: $r = p/(1 + e\cos\nu)$(円錐曲線)
  • 比エネルギー $\varepsilon = -\mu/(2a)$ と角運動量 $h$ が保存量
  • $e < 1$: 束縛軌道(楕円)、$e \geq 1$: 非束縛軌道(放物線・双曲線)

次のステップとして、以下の記事も参考にしてください。