You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用p5.js开发操作自定义对象时频繁出现NaN值该如何解决?

问题原因及修复方案

你代码里的NaN问题是由以下两个明确的语法和逻辑错误导致的:

  • 平方运算符使用错误:JavaScript 中 ^ 是按位异或运算符,不是平方运算。你计算距离时写的 (p[i].ry - p[o].ry) ^ 2 逻辑完全错误,很容易算出0值,后续执行 f = -0.001 / (d * d) 就会得到无穷大(Infinity),叠加运算后就会产生 NaN。正确的平方写法是用 ** 运算符,比如 (p[i].ry - p[o].ry) ** 2。
  • 运动更新逻辑写反:你在更新速度的部分写错了代码,把 p[i].vy += p[i].ay 写成了 p[i].ay += p[i].ay,不仅完全没有更新y方向速度,还会让ay的值不断翻倍,很快就会超出合理数值范围产生异常。
  • 额外优化建议:你代码里所有变量都没有加 let/const 声明,全部暴露为全局变量,很容易出现变量污染问题,建议补上变量声明;另外可以给分母加极小值规避d为0的极端场景,原代码的color(255)不会生效,要设置fill(255)才能让绘制的圆显示白色。

修正后的可运行代码

function setup() {
  createCanvas(600, 600);
  background(0);
  // 补变量声明
  const planetnum = 3;
  const p = [];
  for (let u = 0; u < planetnum; u++) {
    p.push({
      rx: 0,
      ry: 0,
      vx: 0,
      vy: 0,
      ax: 0,
      ay: 0,
      m: 10
    });
  }
  p[0].ry = 100;
  p[1].rx = 100;
  p[2].rx = -100;
}

function draw() {
  background(0);
  translate(width / 2, height / 2);
  scale(1, -1);
  fill(255);
  const planetnum = p.length;
  
  // 计算受力
  for (let i = 0; i < planetnum; i++) {
    p[i].ax = 0;
    p[i].ay = 0;
    for (let o = 0; o < planetnum; o++) {
      if (o !== i) {
        // 修正平方运算
        const dx = p[i].rx - p[o].rx;
        const dy = p[i].ry - p[o].ry;
        const d = sqrt(dx ** 2 + dy ** 2);
        // 加极小值避免d为0时除以0
        const f = -0.001 / (d * d + Number.EPSILON);
        const angle = Math.atan2(dy, dx);
        p[i].ax += f * d * Math.cos(angle) / p[i].m;
        p[i].ay += f * d * Math.sin(angle) / p[i].m;
      }
    }
    // 修正速度更新逻辑
    p[i].vx += p[i].ax;
    p[i].vy += p[i].ay;
    p[i].rx += p[i].vx;
    p[i].ry += p[i].vy;
  }

  // 绘制行星
  for (let i = 0; i < planetnum; i++) {
    circle(p[i].rx, p[i].ry, 10);
  }
}

HTML部分不需要修改,直接替换JS代码即可正常运行。

内容的提问来源于stack exchange,提问作者Pablo Alonso Esteban

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 14:06:07