从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解析解。
🧭 问题设定:三体系统的基本假设
假设我们有三个质量分别为 m 1 , m 2 , m 3 m_1, m_2, m_3 m1,m2,m3 的天体,位置向量分别为:
- r 1 ( t ) \mathbf{r}_1(t) r1(t)
- r 2 ( t ) \mathbf{r}_2(t) r2(t)
- r 3 ( t ) \mathbf{r}_3(t) r3(t)
在牛顿引力定律下,每个天体受到其余两个天体的引力,总加速度由牛顿第二定律( F = m a \mathbf{F} = m\mathbf{a} F=ma)给出。
📐 一般形式的运动方程(牛顿引力 + 牛顿第二定律)
对第一个天体 m 1 m_1 m1,其加速度为:
m 1 d 2 r 1 d t 2 = G m 1 m 2 ∣ r 2 − r 1 ∣ 3 ( r 2 − r 1 ) + G m 1 m 3 ∣ r 3 − r 1 ∣ 3 ( r 3 − r 1 ) m_1 \frac{d^2 \mathbf{r}_1}{dt^2} = G \frac{m_1 m_2}{|\mathbf{r}_2 - \mathbf{r}_1|^3} (\mathbf{r}_2 - \mathbf{r}_1) + G \frac{m_1 m_3}{|\mathbf{r}_3 - \mathbf{r}_1|^3} (\mathbf{r}_3 - \mathbf{r}_1) m1dt2d2r1=G∣r2−r1∣3m1m2(r2−r1)+G∣r3−r1∣3m1m3(r3−r1)
类似地,对 m 2 , m 3 m_2, m_3 m2,m3 分别有:
m 2 d 2 r 2 d t 2 = G m 2 m 1 ∣ r 1 − r 2 ∣ 3 ( r 1 − r 2 ) + G m 2 m 3 ∣ r 3 − r 2 ∣ 3 ( r 3 − r 2 ) m_2 \frac{d^2 \mathbf{r}_2}{dt^2} = G \frac{m_2 m_1}{|\mathbf{r}_1 - \mathbf{r}_2|^3} (\mathbf{r}_1 - \mathbf{r}_2) + G \frac{m_2 m_3}{|\mathbf{r}_3 - \mathbf{r}_2|^3} (\mathbf{r}_3 - \mathbf{r}_2) m2dt2d2r2=G∣r1−r2∣3m2m1(r1−r2)+G∣r3−r2∣3m2m3(r3−r2)
m 3 d 2 r 3 d t 2 = G m 3 m 1 ∣ r 1 − r 3 ∣ 3 ( r 1 − r 3 ) + G m 3 m 2 ∣ r 2 − r 3 ∣ 3 ( r 2 − r 3 ) m_3 \frac{d^2 \mathbf{r}_3}{dt^2} = G \frac{m_3 m_1}{|\mathbf{r}_1 - \mathbf{r}_3|^3} (\mathbf{r}_1 - \mathbf{r}_3) + G \frac{m_3 m_2}{|\mathbf{r}_2 - \mathbf{r}_3|^3} (\mathbf{r}_2 - \mathbf{r}_3) m3dt2d2r3=G∣r1−r3∣3m3m1(r1−r3)+G∣r2−r3∣3m3m2(r2−r3)
⚠️ 为什么不稳定?
1. 非线性耦合微分方程组
这三组式子彼此高度耦合:每个加速度都依赖于另外两个天体的位置,而且这种依赖是非线性(距离的三次方在分母)。
这是典型的非线性二阶常微分方程组,形式上如下:
d 2 r i d t 2 = ∑ j ≠ i G m j r j − r i ∣ r j − r i ∣ 3 , i = 1 , 2 , 3 \frac{d^2 \mathbf{r}_i}{dt^2} = \sum_{j \ne i} G m_j \frac{\mathbf{r}_j - \mathbf{r}_i}{|\mathbf{r}_j - \mathbf{r}_i|^3}, \quad i = 1,2,3 dt2d2ri=j=i∑Gmj∣rj−ri∣3rj−ri,i=1,2,3
这种系统存在如下三大特性:
- 不可分解成单体运动 + 微扰项
- 无法通过代数方法求出通解
- 随时间演化会展现出对初始条件的极度敏感
2. 初始条件敏感性(混沌特征)
在数值模拟中,即使两个三体系统初始位置差异为 10 − 10 10^{-10} 10−10 米,几十个周期后轨道会完全不同。
这是混沌系统的定义特征:
初始条件微小扰动会被放大,导致长期行为完全不可预测。
3. 守恒定律约束不足以稳定系统
虽然系统满足以下守恒定律:
-
总动量守恒:
∑ i = 1 3 m i d r i d t = 常量 \sum_{i=1}^3 m_i \frac{d \mathbf{r}_i}{dt} = \text{常量} i=1∑3midtdri=常量
-
总能量守恒:
E = ∑ i = 1 3 1 2 m i v i 2 − ∑ i < j G m i m j ∣ r i − r j ∣ E = \sum_{i=1}^3 \frac{1}{2} m_i v_i^2 - \sum_{i<j} \frac{G m_i m_j}{|\mathbf{r}_i - \mathbf{r}_j|} E=i=1∑321mivi2−i<j∑∣ri−rj∣Gmimj
但这些守恒量(常数)无法限制轨道在高维空间的发散演化,只是提供一些“整体约束”。
📉 所以为什么不能稳定运行?
从物理角度总结三点:
- 多体引力是非线性且时变的力学系统;
- 无解析解(除极少对称情况),必须数值求解;
- 即使数值解,也极度依赖初始条件,最终表现为混沌轨道;
🎯 实际结果是什么?
小说中三体行星文明面临的核心困境——无法预测三颗恒星的运动。正是这个真实的物理问题,使得三体文明的“乱纪元”和“恒纪元”交替成为必然,也解释了为什么他们需要寻找新的家园。数值模拟证实了这种不稳定性是三体系统的内在属性,而非外部干扰的结果。
三体运动的模拟动画
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import matplotlib.patches as patches
from matplotlib.widgets import Button
from collections import deque
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
class ThreeBodySystem:
def __init__(self, masses, positions, velocities, G=1.0):
"""
三体系统
masses: [m1, m2, m3] 三个天体的质量
positions: [[x1,y1], [x2,y2], [x3,y3]] 初始位置
velocities: [[vx1,vy1], [vx2,vy2], [vx3,vy3]] 初始速度
G: 引力常数
"""
self.masses = np.array(masses)
self.positions = np.array(positions, dtype=float)
self.velocities = np.array(velocities, dtype=float)
self.G = G
# 轨迹历史记录 - 为每个天体单独记录
self.trail_length = 800
self.trails = [deque(maxlen=self.trail_length) for _ in range(3)]
# 初始化轨迹记录
for i in range(3):
self.trails[i].append([self.positions[i][0], self.positions[i][1]])
self.dt = 0.005 # 基础时间步长
self.speed_multiplier = 1.0 # 速度倍数
self.time = 0
# 天体属性
self.colors = ['#FF6B35', '#004E89', '#00A86B'] # 橙色、深蓝、绿色
self.names = ['恒星Alpha', '恒星Beta', '恒星Gamma']
self.base_sizes = [300, 250, 280]
# 统计数据记录
self.energy_history = deque(maxlen=500)
self.distance_history = {'AB': deque(maxlen=500),
'AC': deque(maxlen=500),
'BC': deque(maxlen=500)}
def set_speed_multiplier(self, multiplier):
"""设置速度倍数"""
self.speed_multiplier = max(0.1, min(10.0, multiplier))
def compute_gravitational_forces(self):
"""计算每个天体受到的引力"""
forces = np.zeros_like(self.positions)
for i in range(3):
for j in range(3):
if i != j:
# 位置差矢量: 从i指向j
r_vec = self.positions[j] - self.positions[i]
r_magnitude = np.linalg.norm(r_vec)
# 避免数值奇点
if r_magnitude > 1e-8:
# 万有引力: F = G*m1*m2/r^2 * 单位矢量
force_magnitude = self.G * self.masses[i] * self.masses[j] / (r_magnitude ** 3)
forces[i] += force_magnitude * r_vec
return forces
def runge_kutta_4th_order(self):
"""四阶龙格-库塔法数值积分(带速度控制)"""
effective_dt = self.dt * self.speed_multiplier
# 当前状态
pos = self.positions.copy()
vel = self.velocities.copy()
# k1 计算
k1_vel = vel
k1_acc = self.compute_gravitational_forces() / self.masses.reshape(-1, 1)
# k2 计算
pos_k2 = pos + 0.5 * effective_dt * k1_vel
self.positions = pos_k2 # 临时更新位置用于力计算
k2_vel = vel + 0.5 * effective_dt * k1_acc
k2_acc = self.compute_gravitational_forces() / self.masses.reshape(-1, 1)
# k3 计算
pos_k3 = pos + 0.5 * effective_dt * k2_vel
self.positions = pos_k3
k3_vel = vel + 0.5 * effective_dt * k2_acc
k3_acc = self.compute_gravitational_forces() / self.masses.reshape(-1, 1)
# k4 计算
pos_k4 = pos + effective_dt * k3_vel
self.positions = pos_k4
k4_vel = vel + effective_dt * k3_acc
k4_acc = self.compute_gravitational_forces() / self.masses.reshape(-1, 1)
# 最终更新
self.positions = pos + effective_dt * (k1_vel + 2 * k2_vel + 2 * k3_vel + k4_vel) / 6
self.velocities = vel + effective_dt * (k1_acc + 2 * k2_acc + 2 * k3_acc + k4_acc) / 6
# 记录轨迹
for i in range(3):
self.trails[i].append([self.positions[i][0], self.positions[i][1]])
self.time += effective_dt
def calculate_total_energy(self):
"""计算系统总能量(动能+势能)"""
# 动能
kinetic_energy = 0
for i in range(3):
v_squared = np.sum(self.velocities[i] ** 2)
kinetic_energy += 0.5 * self.masses[i] * v_squared
# 引力势能
potential_energy = 0
for i in range(3):
for j in range(i + 1, 3):
r = np.linalg.norm(self.positions[i] - self.positions[j])
if r > 1e-8:
potential_energy -= self.G * self.masses[i] * self.masses[j] / r
return kinetic_energy + potential_energy
def update_statistics(self):
"""更新统计数据"""
# 总能量
energy = self.calculate_total_energy()
self.energy_history.append(energy)
# 天体间距离
r_AB = np.linalg.norm(self.positions[0] - self.positions[1])
r_AC = np.linalg.norm(self.positions[0] - self.positions[2])
r_BC = np.linalg.norm(self.positions[1] - self.positions[2])
self.distance_history['AB'].append(r_AB)
self.distance_history['AC'].append(r_AC)
self.distance_history['BC'].append(r_BC)
class SpeedController:
"""速度控制器类"""
def __init__(self, system):
self.system = system
self.speed_levels = [0.1, 0.25, 0.5, 1.0, 2.0, 4.0, 8.0]
self.current_level = 3 # 默认1.0倍速
def speed_up(self, event=None):
"""加速"""
if self.current_level < len(self.speed_levels) - 1:
self.current_level += 1
self.current_level = min(self.current_level, len(self.speed_levels)-1)
self.system.set_speed_multiplier(self.speed_levels[self.current_level])
def slow_down(self, event=None):
"""减速"""
if self.current_level > 0:
self.current_level -= 1
self.current_level = max(self.current_level, 0)
self.system.set_speed_multiplier(self.speed_levels[self.current_level])
def reset_speed(self, event=None):
"""重置到正常速度"""
self.current_level = 3
self.system.set_speed_multiplier(self.speed_levels[self.current_level])
def get_current_speed_text(self):
"""获取当前速度显示文本"""
speed = self.speed_levels[self.current_level]
return f"播放速度: {speed:.1f}x"
def create_three_body_animation():
"""创建带速度控制的三体运动动画"""
# 初始化系统 - 选择一个展现混沌特性的配置
masses = [1.5, 1.0, 1.2] # 三个不同质量的恒星
# 三角形初始配置,但有适当的速度产生复杂轨道
positions = [
[-2.0, 0.0], # Alpha星
[1.0, 1.732], # Beta星
[1.0, -1.732] # Gamma星
]
velocities = [
[0.2, 0.8], # Alpha星初始速度
[-0.6, -0.2], # Beta星初始速度
[0.4, -0.6] # Gamma星初始速度
]
system = ThreeBodySystem(masses, positions, velocities, G=3.0)
speed_controller = SpeedController(system)
# 创建图形界面
fig = plt.figure(figsize=(19, 12), facecolor='#0a0a0a')
# 主动画区域 (左侧大图)
ax_main = plt.subplot2grid((3, 5), (0, 0), colspan=3, rowspan=3, facecolor='#0a0a0a')
# 监控面板 (右侧)
ax_energy = plt.subplot2grid((3, 5), (0, 3), colspan=2, facecolor='#0a0a0a')
ax_distances = plt.subplot2grid((3, 5), (1, 3), colspan=2, facecolor='#0a0a0a')
ax_info = plt.subplot2grid((3, 5), (2, 3), colspan=2, facecolor='#0a0a0a')
# 在底部为按钮留出空间
plt.subplots_adjust(bottom=0.15)
# 创建速度控制按钮
button_height = 0.04
button_width = 0.08
button_y = 0.02
# 减速按钮
ax_slow = plt.axes([0.25, button_y, button_width, button_height])
btn_slow = Button(ax_slow, '减速', color='#FF4444', hovercolor='#FF6666')
btn_slow.label.set_color('white')
btn_slow.label.set_fontweight('bold')
# 重置按钮
ax_reset = plt.axes([0.35, button_y, button_width, button_height])
btn_reset = Button(ax_reset, '正常', color='#4CAF50', hovercolor='#6BCF7F')
btn_reset.label.set_color('white')
btn_reset.label.set_fontweight('bold')
# 加速按钮
ax_fast = plt.axes([0.45, button_y, button_width, button_height])
btn_fast = Button(ax_fast, '加速', color='#2196F3', hovercolor='#42A5F5')
btn_fast.label.set_color('white')
btn_fast.label.set_fontweight('bold')
# 暂停/继续按钮
ax_pause = plt.axes([0.55, button_y, button_width, button_height])
btn_pause = Button(ax_pause, '暂停', color='#FF9800', hovercolor='#FFB74D')
btn_pause.label.set_color('white')
btn_pause.label.set_fontweight('bold')
# 速度显示文本
speed_text = fig.text(0.65, button_y + button_height / 2,
speed_controller.get_current_speed_text(),
fontsize=12, color='white', va='center', weight='bold')
# 设置主画布
ax_main.set_xlim(-8, 8)
ax_main.set_ylim(-8, 8)
ax_main.set_aspect('equal')
ax_main.set_facecolor('#0a0a0a')
ax_main.tick_params(colors='white')
ax_main.set_xlabel('X 坐标', color='white', fontsize=14)
ax_main.set_ylabel('Y 坐标', color='white', fontsize=14)
ax_main.set_title('三体问题:三颗恒星的混沌舞蹈', color='white', fontsize=16, pad=20)
# 创建星空背景
np.random.seed(123)
star_x = np.random.uniform(-8, 8, 200)
star_y = np.random.uniform(-8, 8, 200)
star_sizes = np.random.uniform(0.5, 3, 200)
ax_main.scatter(star_x, star_y, c='white', s=star_sizes, alpha=0.4)
# 添加网格
ax_main.grid(True, alpha=0.15, color='gray', linestyle='-', linewidth=0.5)
# 初始化绘图元素
# 1. 三个恒星天体
stars = []
for i in range(3):
star = ax_main.scatter([], [], s=system.base_sizes[i],
c=system.colors[i], edgecolors='white',
linewidth=3, alpha=0.95, zorder=20)
stars.append(star)
# 2. 三条轨迹线
orbit_trails = []
for i in range(3):
trail, = ax_main.plot([], [], color=system.colors[i],
linewidth=2.5, alpha=0.8, zorder=10)
orbit_trails.append(trail)
# 3. 引力连接线
gravity_lines = []
gravity_colors = ['yellow', 'orange', 'red']
line_pairs = [(0, 1), (0, 2), (1, 2)]
for i, (a, b) in enumerate(line_pairs):
line, = ax_main.plot([], [], color=gravity_colors[i],
alpha=0.4, linewidth=2, linestyle='--', zorder=5)
gravity_lines.append(line)
# 4. 恒星标签
star_labels = []
for i in range(3):
label = ax_main.text(0, 0, system.names[i], fontsize=12, color='white',
ha='center', va='center', weight='bold',
bbox=dict(boxstyle="round,pad=0.3", facecolor=system.colors[i], alpha=0.7))
star_labels.append(label)
# 5. 信息显示
status_text = ax_main.text(0.02, 0.98, '', transform=ax_main.transAxes,
fontsize=12, color='white', verticalalignment='top',
bbox=dict(boxstyle="round,pad=0.5",
facecolor="black", alpha=0.8))
# 设置监控图表
for ax in [ax_energy, ax_distances]:
ax.set_facecolor('#0a0a0a')
ax.tick_params(colors='white')
ax.grid(True, alpha=0.3, color='gray')
# 能量图
ax_energy.set_title('系统总能量守恒', color='white', fontsize=12)
ax_energy.set_ylabel('总能量', color='white')
energy_line, = ax_energy.plot([], [], color='cyan', linewidth=2)
# 距离图
ax_distances.set_title('恒星间距离变化', color='white', fontsize=12)
ax_distances.set_ylabel('距离', color='white')
ax_distances.set_xlabel('时间步', color='white')
dist_lines = {}
dist_colors = ['red', 'blue', 'green']
dist_labels = ['Alpha-Beta', 'Alpha-Gamma', 'Beta-Gamma']
for i, key in enumerate(['AB', 'AC', 'BC']):
line, = ax_distances.plot([], [], color=dist_colors[i],
linewidth=2, label=dist_labels[i])
dist_lines[key] = line
ax_distances.legend(fontsize=10)
# 信息面板
ax_info.set_facecolor('#0a0a0a')
ax_info.axis('off')
info_display = ax_info.text(0.05, 0.95, '', transform=ax_info.transAxes,
fontsize=11, color='white', verticalalignment='top')
# 动画状态控制
animation_paused = [False] # 使用列表以便在闭包中修改
def toggle_pause(event):
"""切换暂停/继续"""
animation_paused[0] = not animation_paused[0]
btn_pause.label.set_text('继续' if animation_paused[0] else '暂停')
def update_speed_display():
"""更新速度显示"""
speed_text.set_text(speed_controller.get_current_speed_text())
fig.canvas.draw_idle()
def on_speed_up(event):
speed_controller.speed_up()
update_speed_display()
def on_slow_down(event):
speed_controller.slow_down()
update_speed_display()
def on_reset_speed(event):
speed_controller.reset_speed()
update_speed_display()
# 连接按钮事件
btn_fast.on_clicked(on_speed_up)
btn_slow.on_clicked(on_slow_down)
btn_reset.on_clicked(on_reset_speed)
btn_pause.on_clicked(toggle_pause)
def animate_frame(frame):
# 如果暂停则不更新
if animation_paused[0]:
return (stars + orbit_trails + gravity_lines + star_labels +
[status_text, energy_line] + list(dist_lines.values()) + [info_display])
# 执行物理计算 - 每帧多步提高精度
steps_per_frame = max(1, int(3 / max(0.1, system.speed_multiplier)))
for _ in range(steps_per_frame):
system.runge_kutta_4th_order()
system.update_statistics()
# 更新三个恒星的位置
for i in range(3):
# 更新恒星位置
current_pos = system.positions[i].reshape(1, -1)
stars[i].set_offsets(current_pos)
# 添加脉动效果
pulse = 1 + 0.2 * np.sin(system.time * 4 + i * 2)
stars[i].set_sizes([system.base_sizes[i] * pulse])
# 更新标签位置
star_labels[i].set_position((system.positions[i][0] + 0.5,
system.positions[i][1] + 0.5))
# 更新轨迹
for i in range(3):
if len(system.trails[i]) > 1:
trail_array = np.array(list(system.trails[i]))
orbit_trails[i].set_data(trail_array[:, 0], trail_array[:, 1])
# 更新引力连接线
for i, (a, b) in enumerate(line_pairs):
pos_a = system.positions[a]
pos_b = system.positions[b]
gravity_lines[i].set_data([pos_a[0], pos_b[0]], [pos_a[1], pos_b[1]])
# 根据距离调整线条粗细和透明度
distance = np.linalg.norm(pos_a - pos_b)
alpha = max(0.2, min(0.8, 5.0 / distance))
linewidth = max(1, min(4, 8.0 / distance))
gravity_lines[i].set_alpha(alpha)
gravity_lines[i].set_linewidth(linewidth)
# 更新状态信息
current_energy = system.calculate_total_energy()
max_velocity = max([np.linalg.norm(v) for v in system.velocities])
status_info = (
f"模拟时间: {system.time:.2f}\n"
f"播放速度: {system.speed_multiplier:.1f}x\n"
f"系统总能量: {current_energy:.4f}\n"
f"最大速度: {max_velocity:.3f}\n"
f"计算步数: {frame * steps_per_frame}\n"
f"\n三体位置坐标:\n"
)
for i in range(3):
pos = system.positions[i]
vel_mag = np.linalg.norm(system.velocities[i])
status_info += f"{system.names[i]}: ({pos[0]:.2f}, {pos[1]:.2f})\n"
status_info += f" 速度: {vel_mag:.3f}\n"
status_text.set_text(status_info)
# 更新能量图
if len(system.energy_history) > 1:
time_points = list(range(len(system.energy_history)))
energy_line.set_data(time_points, list(system.energy_history))
ax_energy.relim()
ax_energy.autoscale_view()
# 更新距离图
if len(system.distance_history['AB']) > 1:
time_points = list(range(len(system.distance_history['AB'])))
for key in ['AB', 'AC', 'BC']:
dist_lines[key].set_data(time_points, list(system.distance_history[key]))
ax_distances.relim()
ax_distances.autoscale_view()
# 更新信息面板
min_dist = min([list(system.distance_history[key])[-1]
for key in system.distance_history.keys()
if len(system.distance_history[key]) > 0])
info_text = (
"=== 三体系统状态 ===\n\n"
f"恒星质量:\n"
f" {system.names[0]}: {system.masses[0]:.1f}M☉\n"
f" {system.names[1]}: {system.masses[1]:.1f}M☉\n"
f" {system.names[2]}: {system.masses[2]:.1f}M☉\n\n"
f"最近距离: {min_dist:.3f}\n"
f"引力常数: {system.G:.1f}\n\n"
"观察要点:\n"
"* 轨道的不规则性\n"
"* 近距离遭遇事件\n"
"* 能量守恒定律\n"
"* 混沌敏感依赖性\n\n"
"控制说明:\n"
"* 加速/减速按钮调节播放速度\n"
"* 暂停按钮停止/继续动画\n"
"* 正常按钮重置为1x速度"
)
info_display.set_text(info_text)
return (stars + orbit_trails + gravity_lines + star_labels +
[status_text, energy_line] + list(dist_lines.values()) + [info_display])
# 创建动画对象
anim = FuncAnimation(fig, animate_frame, frames=3000,
interval=30, blit=False, repeat=True, cache_frame_data=False)
# 总标题
fig.suptitle('三体问题数值模拟:混沌引力系统(速度可控)',
fontsize=18, color='white', y=0.96)
# 底部说明
fig.text(0.02, 0.085,
'物理原理: 三个质量不等的恒星在万有引力作用下的非周期运动 | '
'混沌特征: 轨道不可预测、对初始条件敏感、长期行为无法确定 | '
'数值方法: 四阶龙格-库塔法求解牛顿引力方程组',
fontsize=10, color='white',
bbox=dict(boxstyle="round,pad=0.5", facecolor="#1a1a2e", alpha=0.9))
plt.tight_layout()
plt.subplots_adjust(top=0.92, bottom=0.18)
plt.show()
return anim
# 启动三体动画
print("🌟 启动三体恒星系统动态模拟(带速度控制)...")
print("\n系统配置:")
print("* 三颗质量不等的恒星: Alpha(1.5M☉), Beta(1.0M☉), Gamma(1.2M☉)")
print("* 初始三角形配置,赋予复杂初始速度")
print("* 高精度数值积分(RK4)确保长期稳定性")
print("\n可视化特征:")
print("✓ 三个不同颜色的恒星实时运动")
print("✓ 彩色轨迹显示历史路径")
print("✓ 虚线显示引力相互作用")
print("✓ 恒星大小脉动模拟真实效果")
print("✓ 实时监控能量守恒和距离变化")
print("\n新增速度控制功能:")
print("🎮 减速按钮: 降低播放速度(0.1x-8x)")
print("🎮 加速按钮: 提高播放速度(0.1x-8x)")
print("🎮 正常按钮: 重置为1x正常速度")
print("🎮 暂停按钮: 暂停/继续动画播放")
print("🎮 实时速度显示: 当前播放倍数")
print("\n观察重点:")
print("🔍 轨道的复杂性和不可预测性")
print("🔍 恒星间距离的剧烈变化")
print("🔍 近距离遭遇引起的轨道突变")
print("🔍 系统总能量的精确守恒")
print("\n操作提示:")
print("💡 使用加速功能快速观察长期行为")
print("💡 使用减速功能仔细研究细节变化")
print("💡 暂停功能方便截图和观察")
print("\n正在加载动画...")
# 运行动画
animation = create_three_body_animation()
print("🎬 三体动画已启动!使用底部按钮控制播放速度...")
参考
- 三体问题究竟是什么?为什么说科学的尽头是神学?