首页 > 解决方案 > 为什么我的对象不断获得 NaN 值?

问题描述

我一直在搞乱一个名为 p5.js 的库,但在尝试修改对象的值时遇到了问题。在创建数组并推送对象后,我检查对象并且它有许多 NaN 值。此代码可以在 editor.p5js.org 中免费运行,以备不时之需。提前致谢。

function setup() {
  createCanvas(600, 600);

  background(0);

  p = [];
  planetnum = 3; //Set one more 
  for (u = 0; u < planetnum; u++) {
    p.push({
      rx: 0,
      ry: 0,
      vx: 0,
      vy: 0,
      ax: 0,
      ay: 0,
      m: 10
    });
  }
  for (u = 0; u < planetnum; u++) {
    p[u].rx = 0;
    p[u].ry = 0;
    p[u].vx = 0;
    p[u].vy = 0;
    p[u].ax = 0;
    p[u].ay = 0;
    p[u].m = 10;
  }

  p[0].ry = 100;
  p[1].rx = 100;
  p[2].rx = -100;
  console.log(p[1]);
}

function draw() {
  background(0);
  translate(width / 2, height / 2);
  scale(1, -1);
  console.log("Working");
  color(255);
  //Calculate next position
  for (i = 0; i < planetnum; i++) {
    p[i].ax = 0;
    p[i].ay = 0;
    console.log(p[i]);
    for (o = 0; o < planetnum; o++) {
      if (o != i) {
        d = sqrt((p[i].ry - p[o].ry) ^ 2 + (p[i].rx - p[o].rx) ^ 2);
        f = -0.001 / (d * d);
        angle = Math.atan2((p[i].ry - p[o].ry), (p[i].rx - p[o].rx));

        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].ay += p[i].ay;
    p[i].rx += p[i].vx;
    p[i].ry += p[i].vy;
  }

  //Draw circles
  for (i = 0; i < planetnum; i++) {
    circle(p[i].rx, p[i].ry, 10);
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>

标签: javascriptp5.js

解决方案


我猜当你写这段代码时:

d = sqrt((p[i].ry - p[o].ry) ^ 2 + (p[i].rx - p[o].rx) ^ 2);

您的意图是对每个增量进行平方。但是,在 JavaScript^中是按位 XOR 运算符,而不是指数运算符。这可能导致您取 -1 的平方根,即 NaN。这解决了 NaN 问题:

d = sqrt((p[i].ry - p[o].ry) ** 2 + (p[i].rx - p[o].rx) ** 2);

注意:在某些已失效的浏览器上,您可能需要使用Math.pow(p[i].ry - p[o].ry, 2),您也可以考虑使用 p5.js 的 dist 函数:dist(p[i].rx, p[i].ry, p[o].rx, p[o].ry)

function setup() {
  createCanvas(600, 600);

  background(0);

  p = [];
  planetnum = 3; //Set one more 
  for (u = 0; u < planetnum; u++) {
    p.push({
      rx: 0,
      ry: 0,
      vx: 0,
      vy: 0,
      ax: 0,
      ay: 0,
      m: 10
    });
  }
  for (u = 0; u < planetnum; u++) {
    p[u].rx = 0;
    p[u].ry = 0;
    p[u].vx = 0;
    p[u].vy = 0;
    p[u].ax = 0;
    p[u].ay = 0;
    p[u].m = 10;
  }

  p[0].ry = 100;
  p[1].rx = 100;
  p[2].rx = -100;
  console.log(p[1]);
}

function mouseClicked() {
  console.log("Debug:");
  for (i = 0; i < planetnum; i++) {
    console.log(p[i]);
  }
}

function draw() {
  background(0);
  translate(width / 2, height / 2);
  scale(1, -1);
  color(255);
  //Calculate next position
  for (i = 0; i < planetnum; i++) {
    p[i].ax = 0;
    p[i].ay = 0;
    for (o = 0; o < planetnum; o++) {
      if (o != i) {
        d = sqrt((p[i].ry - p[o].ry) ** 2 + (p[i].rx - p[o].rx) ** 2);
        f = -0.001 / (d * d);
        angle = Math.atan2((p[i].ry - p[o].ry), (p[i].rx - p[o].rx));

        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].ay += p[i].ay;
    p[i].rx += p[i].vx;
    p[i].ry += p[i].vy;
  }

  //Draw circles
  for (i = 0; i < planetnum; i++) {
    circle(p[i].rx, p[i].ry, 10);
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>


推荐阅读