【问题标题】:Object Variables go NaN after a few frames几帧后对象变量变为 NaN
【发布时间】:2018-06-19 11:58:36
【问题描述】:

我正在做一个简单的 n 体模拟。现在,我正在“暴力破解”它,这意味着我每帧计算每个对象对每个其他对象施加的每一个力。

我现在的问题是,如果我选择大量对象,例如 2000 个,在某些情况下,在开始时,对象“行星”会消失大约 2 帧。当我通过将System.out.println(PlanetHandler.planets.get(0).position.x); 添加到主循环中来检查发生了什么时,我得到了

487.0
486.99454
NaN
NaN

通过注释掉一些东西和反复试验,我发现问题出在:

private static void computeAndSetPullForce(Planet planet)
{
    for(Planet otherPlanet : planets)
    {
        //Also here, if we are deleting the planet, don't interact with it.
        if(otherPlanet != planet && !otherPlanet.delete)
        {
            //First we get the x,y and magnitudal distance between the two bodies.
            int xDist = (int) (otherPlanet.position.x - planet.position.x);
            int yDist = (int) (otherPlanet.position.y - planet.position.y);
            float dist = Vector2Math.distance(planet.position, otherPlanet.position);

            //Now we compute first the total and then the component forces
            //Depending on choice, use r or r^2
            float force = Constants.GRAVITATIONAL_CONSTANT * ((planet.mass*otherPlanet.mass)/(dist*dist)); 
            float forceX = force * xDist/dist;
            float forceY = force * yDist/dist;

            //Given the component forces, we construct the force vector and apply it to the body.
            Vector2 forceVec = new Vector2(forceX, forceY);
            planet.force = Vector2Math.add(planet.force, forceVec);
        }
    }
}

“行星”列表是CopyOnWriteArray<Planets>。 我已经有一段时间了,但还没有弄清楚是什么可能导致值(位置,速度)变南。也许有这方面经验或通常擅长这类事情的人可以帮助我。

【问题讨论】:

  • 唯一似乎能够在您发布的内容中编辑planet.position 是Vector2Math.distance
  • 您使用距离公式(暗示平方根),但您始终使用结果的平方。您可以通过将长度平方来节省一些速度。 (始终尽量减少物理引擎中的 sqrt/pow 调用量)
  • 但是我怎么能计算`浮动力 = Constants.GRAVITATIONAL_CONSTANT * ((planet.massotherPlanet.mass)/(distdist));浮动 forceX = 力 * xDist/dist;浮动 forceY = force * yDist/dist;`?如果我是正确的,我只能通过使用几何来计算组件。
  • float 对于任何严重的使用来说都是一种糟糕的浮点类型,并且只有大约 7-8 位的精度。至少更喜欢double

标签: java simulation physics


【解决方案1】:

这是 JVM 为您提供 NAN 的典型情况。你遇到的是零除以零( 0/0 ),在数学中是一种不确定的形式。

如果float dist = Vector2Math.distance(planet.position, otherPlanet.position);

返回 0。

下一条语句

float force = Constants.GRAVITATIONAL_CONSTANT * ((planet.mass*otherPlanet.mass)/(dist*dist)); 

你计算的力除以零。

另外,我建议您在需要精度时使用 BigDecimal。也可以参考其中一个答案here

【讨论】:

  • 除以零会引发异常(对于整数)或给您无穷大(对于双精度数和浮点数)。零除以零得到一个 NaN,不过
  • @PhilBarr 我的错,它的 0/0!更新
  • 我自己看不到 - 似乎您可能想在其中放置大量 System.out.println() 调试语句,无论您有什么部门。也许你的行星彼此重叠?此外,0/0 并不是唯一能让你获得 NaN 的东西。 sqrt(x
  • 还有其他可能导致 NaN 的因素。像 sqrt(x
  • 那个东西是iota的乘数,通常是虚数:)
猜你喜欢
  • 2017-03-03
  • 2014-08-07
  • 1970-01-01
  • 2018-07-25
  • 1970-01-01
  • 2011-03-06
  • 2012-04-22
  • 2023-02-04
  • 1970-01-01
相关资源
最近更新 更多