首页 > 解决方案 > n体模拟幻象力

问题描述

在我的 n 体模拟中,我有大约 1k 个粒子飞来飞去。我将位置存储为浮点数。我遇到的一个问题是,每次我运行代码时,当两个粒子彼此非常接近(基本上是相同的位置)时,它们会被极大地加速。通常粒子的行为是平滑的。

if((planet.position.x != otherPlanet.position.x && planet.position.y != otherPlanet.position.y) && !otherPlanet.delete)
        {
            //First we get the x,y and magnitudal distance between the two bodies.
            float xDist = (otherPlanet.position.x - planet.position.x);
            float yDist = (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);
            otherPlanet.force = Vector2Math.subtract(otherPlanet.force, forceVec);
        }

我还没有找到关于这个主题的任何内容,但这是我做错了什么还是我必须实现最大加速度或粒子之间的最小距离?

标签: javasimulationgame-physics

解决方案


模拟世界与现实世界有点不同,为了做出好的模拟,我们需要添加一些限制。

问题:

当两个粒子彼此真正靠近时,它们就会以极快的速度向外爆炸。

原因

原因很简单,重力与两个物体之间的距离平方成反比。当两个物体靠得太近时,半径(它们之间的距离)变得非常小,作用在它们上的力变得非常非常大。

解决方案

为两个粒子可以接近多少添加一个虚拟限制。虚拟限制是指该限制仅在值上,而不在模拟上。例如。如果它们之间的距离小于 5(阈值),则将距离设置为 5。

代码中的更改

if((planet.position.x != otherPlanet.position.x && planet.position.y != otherPlanet.position.y) && !otherPlanet.delete)
        {
            //First we get the x,y and magnitudal distance between the two bodies.
            float xDist = (otherPlanet.position.x - planet.position.x);
            float yDist = (otherPlanet.position.y - planet.position.y);
             // add a limit to xDist and yDist
             if(xDist<5)
                xDist=5;
             if(yDist<5)
                yDist=5;
            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);
            otherPlanet.force = Vector2Math.subtract(otherPlanet.force, forceVec);
        }

当然,您希望将 5 更改为适合您模拟的值。


推荐阅读