3

更新; -将 j=0 更改为 j=i 允许多达 700 个粒子以平滑的帧速率

我试图用数百个粒子来模拟二维水,这些粒子有 Vector2s 声明它们的位置,Vector2s 声明它们的速度。

在碰撞检测方面,我的程序不喜欢超过 450 个粒子,尽管只使用了毕达哥拉斯定理。

这是主类中的碰撞检测;

        for (int i = 0; i < particleList.Count; i++)
            {
                for (int j = 0; j < particleList.Count; j++)
                {
                    if (distanceBetween(particleList[i].position, particleList[j].position) < reactDistance)
                    {
                        if (particleList[i].position.X > particleList[j].position.X) //x axis
                        {
                            particleList[i].velocity.X += repelSpeed;
                            particleList[j].velocity.X -= repelSpeed;

                            particleList[i].position.X -= attractSpeed;
                            particleList[j].position.X += attractSpeed;
                        }
                        else
                        {
                            particleList[i].velocity.X -= repelSpeed;
                            particleList[j].velocity.X += repelSpeed;

                            particleList[i].position.X += attractSpeed;
                            particleList[j].position.X -= attractSpeed;
                        }

                        if (particleList[i].position.Y > particleList[j].position.Y) //y axis
                        {
                            particleList[i].velocity.Y += repelSpeed;
                            particleList[j].velocity.Y -= repelSpeed;

                            particleList[i].position.Y -= attractSpeed;
                            particleList[j].position.Y += attractSpeed;
                        }
                        else
                        {
                            particleList[i].velocity.Y -= repelSpeed;
                            particleList[j].velocity.Y += repelSpeed;

                            particleList[i].position.Y += attractSpeed;
                            particleList[j].position.Y -= attractSpeed;
                        }
                    }
                }
            }

这是 distanceBetween(v1, v2) 方法;

        public float distanceBetween(Vector2 a, Vector2 b)
    {
        float xDist, yDist, distTo;
        if (a.X > b.X) //x axis
        {
            xDist = a.X - b.X;
        }
        else
        {
            xDist = b.X - a.X;
        }

        if (a.Y > b.Y) //y axis
        {
            yDist = a.Y - b.Y;
        }
        else
        {
            yDist = b.Y - a.Y;
        }
        distTo = (float)(Math.Sqrt((xDist * xDist) + (yDist * yDist)));
        return distTo;
    }

Vector2.Distance(v1, v2) 不会产生明显的性能变化。

如果你想知道吸引速度到底是做什么的;这是我试图形成水集合的糟糕尝试。我不知道该怎么做。

最终我想要这样的东西:http: //grantkot.com/MPM/Liquid.html

4

1 回答 1

2

虽然有一些性能方面可以改进,但最终,粒子的存储将使任何努力相形见绌。

您的算法是O(n^2),对于每个粒子,您再次遍历整个粒子列表。对于n = 700,这是700*700 = 490000循环的执行。此外,许多粒子的检查i过于频繁。如果您在 开始内循环j=i,您将获得明显的加速。

然而,在我看来,这只是一个创可贴。您应该研究更有效的粒子存储,即Quadtree

此外,不是为每个距离计算 sqrt,而是将您比较的距离平方:

distTo = (xDist * xDist) + (yDist * yDist);
...

if(distanceBetween(particleList[i].position, particleList[j].position) < reactDistance * reactDistance)

您甚至可以在循环之前预先计算,这样您就不会每次都有这种开销。

于 2013-11-02T15:42:43.843 回答