几帧后对象变量变为 NaN
Object Variables go NaN after a few frames
我正在做一个简单的 n 体模拟。现在,我是 "bruteforcing",这意味着我计算每帧每个对象对每个其他对象施加的每个力。
我现在的问题是,如果我选择大量对象,比如 2000 个,在某些情况下,对象 "planets" 在开始时会消失大约 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);
}
}
}
"planets" 列表是 CopyOnWriteArray<Planets>
。
我在这方面已经有一段时间了,但还没有弄清楚是什么导致值(位置、速度)变为 Nan。也许对此有一些经验或通常擅长这类事情的人可以帮助我。
这是 JVM 给你一个 NAN 的典型情况。您遇到的是 零除以零( 0/0 ) 在数学中是不确定的形式。
如果float dist = Vector2Math.distance(planet.position, otherPlanet.position);
returns你0个。
下一条语句
float force = Constants.GRAVITATIONAL_CONSTANT * ((planet.mass*otherPlanet.mass)/(dist*dist));
您计算的力除以零。
此外,我建议您在需要精度时使用 BigDecimal。也可以参考其中一个答案 here
我正在做一个简单的 n 体模拟。现在,我是 "bruteforcing",这意味着我计算每帧每个对象对每个其他对象施加的每个力。
我现在的问题是,如果我选择大量对象,比如 2000 个,在某些情况下,对象 "planets" 在开始时会消失大约 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);
}
}
}
"planets" 列表是 CopyOnWriteArray<Planets>
。
我在这方面已经有一段时间了,但还没有弄清楚是什么导致值(位置、速度)变为 Nan。也许对此有一些经验或通常擅长这类事情的人可以帮助我。
这是 JVM 给你一个 NAN 的典型情况。您遇到的是 零除以零( 0/0 ) 在数学中是不确定的形式。
如果float dist = Vector2Math.distance(planet.position, otherPlanet.position);
returns你0个。
下一条语句
float force = Constants.GRAVITATIONAL_CONSTANT * ((planet.mass*otherPlanet.mass)/(dist*dist));
您计算的力除以零。
此外,我建议您在需要精度时使用 BigDecimal。也可以参考其中一个答案 here