使用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
相关产品推荐
相关产品推荐

