代码之家  ›  专栏  ›  技术社区  ›  PeterLikesCode

N体模拟幻影力

  •  0
  • PeterLikesCode  · 技术社区  · 8 年前

    在我的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);
            }
    

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

    1 回复  |  直到 8 年前
        1
  •  1
  •   Lone_Coder    8 年前

    模拟世界和真实世界有点不同,为了使模拟效果好,我们需要增加一些限制。

    问题:

    当两个粒子非常接近时,它们就会爆炸 以惊人的速度向外移动。

    原因

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

    解决方案

    对两个粒子的接近程度添加一个虚拟限制。 虚拟极限我是说极限只在数值上,而不是在 模拟。例如,如果它们之间的距离小于5(A 阈值)将距离设置为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更改为适合您模拟的值。