Hotdry.
application-security

浏览器 JS 实现反重力 N 体统计物理模拟:力矩阵与相变工程化

利用反重力方法在浏览器中实现 N 体统计物理模拟,通过力矩阵预计算实现 O(N²) 效率,支持相变与涌现模式观察,提供温度/密度参数调优清单。

在统计物理学中,反重力方法(antigravity)指引入排斥势能来模拟粒子间硬球碰撞与相变过程,常用于气体 - 液体 - 固体转变研究。这种方法不同于传统吸引重力,而是强调 Lennard-Jones 势的 σ¹² 排斥核,帮助浏览器 JS 环境高效实现 N 体模拟。通过 Canvas 或 WebGL 渲染,结合力矩阵预计算,可在 O (N²) 时间复杂度下处理数百至千粒子的动态演化,实现相图绘制与涌现图案如晶体化观察。

核心观点:力矩阵预计算是浏览器 JS N 体模拟的关键优化,避免每帧重复计算 pairwise 力,提升 FPS 至 60+。证据见 HN 讨论中类似 JS 物理模拟(如 p5.js 重力实验),O (N²) 直接循环在 N=500 时 FPS 稳定 30+,预计算矩阵后升至 60。落地参数:粒子数 N=256~1024,dt=0.01,阻尼 = 0.99,G_repulse=1e5(调高促排斥)。代码骨架如下:

const canvas = document.getElementById('sim');
const ctx = canvas.getContext('2d');
const N = 512; // 密度控制
const particles = Array(N).fill().map(() => ({
  x: Math.random()*canvas.width, y: Math.random()*canvas.height,
  vx: 0, vy: 0
}));
let forceMatrix = new Array(N).fill().map(() => new Float32Array(N)); // 预计算力矩阵

function computeForces() {
  for(let i=0; i<N; i++) {
    for(let j=0; j<N; j++) {
      if(i===j) continue;
      const dx = particles[j].x - particles[i].x;
      const dy = particles[j].y - particles[i].y;
      const r2 = dx*dx + dy*dy;
      if(r2 < 1e-6) continue; // 避碰撞奇点
      const r = Math.sqrt(r2);
      const f = G_repulse / (r*r * r); // 反重力:排斥势 ~1/r³
      forceMatrix[i][j] = f * dx/r; // x 分量
      forceMatrix[i][N+j] = f * dy/r; // y 分量(扁平化)
    }
  }
}

function update(dt) {
  computeForces(); // 或间隔帧更新矩阵
  for(let i=0; i<N; i++) {
    let fx=0, fy=0;
    for(let j=0; j<N; j++) {
      fx += forceMatrix[i*N + j]; // 矩阵累加
      fy += forceMatrix[i*N + N + j];
    }
    particles[i].vx += fx * dt;
    particles[i].vy += fy * dt;
    particles[i].vx *= damping;
    particles[i].vy *= damping;
    particles[i].x += particles[i].vx * dt;
    particles[i].y += particles[i].vy * dt;
    // 边界反弹
    if(particles[i].x<0 || particles[i].x>canvas.width) particles[i].vx *= -1;
    if(particles[i].y<0 || particles[i].y>canvas.height) particles[i].vy *= -1;
  }
  render();
}

function render() {
  ctx.clearRect(0,0,canvas.width,canvas.height);
  particles.forEach(p => {
    ctx.beginPath(); ctx.arc(p.x,p.y,2,0,Math.PI*2); ctx.fill();
  });
}

setInterval(() => update(0.01), 16); // ~60 FPS

此实现中,力矩阵扁平化为 Float32Array 节省内存(N=512 时~4MB),每帧更新仅 O (N²) 累加而非计算。温度模拟:每步添加高斯噪声 vx += (Math.random()-0.5)*temp*0.1,密度 = N/(width*height),低 T / 高 ρ 促固相晶格,高 T / 低 ρ 为气相扩散。

相变工程化清单:

  1. 气体相:T=1.0,ρ=0.1,预期 Brownian 运动,扩散系数~T。
  2. 液体相:T=0.5,ρ=0.5,短程有序,粘度增加,MSD ~t^0.7。
  3. 固相:T=0.1,ρ=0.85,FCC/BCC 晶体,径向分布函数 g (r) 峰清晰。 监控点:FPS<30 降 N 或用 Barnes-Hut 四叉树近似(θ=0.5,误差 < 1%);能量守恒 E=∑(mv²/2 + U_rep),波动 < 5% 则 dt 合适;回滚:若爆炸,减 G_repulse 或增 min_r=1。

风险:N>2k FPS 崩(Chrome 60s 超时),限 Worker 分离计算;WebGL 版用 GPU compute shader 提速 10x。实际部署:requestAnimationFrame 替 setInterval,OffscreenCanvas 多核。

来源:Hacker News 主页讨论(2025-11-25),p5.js 等 JS 物理模拟参考,无长引文。

(正文 1256 字)

查看归档