带有嵌套循环的矢量粒子-未检测到碰撞

Vector particles with nested for loops - collisions not detected

本文关键字:检测 碰撞 粒子 嵌套循环      更新时间:2023-10-16

所以我有一些粒子(椭圆)在屏幕上弹跳。我试着让它们相撞而不是互相越过。为了做到这一点,我必须循环遍历每个粒子并比较它与其他粒子的距离使用嵌套在另一个for循环中的for循环,然后告诉它们的速度在它们的点彼此之间有一定距离时改变,如下所示:

//p.size() returns the size of the particle system (yes it works)
//ofDist() is an open frameworks function that calculates the dist between 2 points
for( int i = 0; i < p.size(); i++){
//        cout << i << endl;
    for(int j = 0; j < p.size(); j++){
//            cout << j << endl;
        pDist[i] = ofDist(p[i].pos.x, p[i].pos.y, p[j].pos.x, p[j].pos.y);
//            cout << pDist[i] << endl;
        if(pDist[i] <= 300){
            p[i].vel.x *= -1;
            p[i].vel.y *= -1;
            p[j].vel.x *= -1;
            p[j].vel.y *= -1;
        }
    }
}

但由于某种神秘的原因,它们仍然彼此擦肩而过,就像它们根本不存在一样。如果我只将应用于2个没有for循环的粒子,那么可以工作:

    pDist[0] = ofDist(p[0].pos.x, p[0].pos.y, p[1].pos.x, p[1].pos.y);
if(pDist[0] <= 300){
    cout << "It's colliding" << endl;
    p[0].vel.x *= -1;
    p[0].vel.y *= -1;
    p[1].vel.x *= -1;
    p[1].vel.y *= -1;
}

粒子存储在一个矢量中。

有什么想法我可以让这个工作与for循环吗?

向量的大小是3,所以p.size() = 3(或者2,现在没有什么区别)我用p.size()代替了代码中的2和3,它没有改变任何东西,所以这不是问题的根源。

更新2 如果有人能让我知道我需要做什么才能不被否决,那将是有帮助的。:/

一个相当大的问题是:

for( int i = 0; i < p.size(); i++){
    for(int j = 0; j < p.size(); j++){

你实际上是在检查每个粒子与它们自己的对比。你还要检查两次粒子碰撞。通过两次检测单个碰撞,并每次反转速度,您实际上什么也没做(a * -1 * -1 = a)。

一个更好的方法是使用一个循环,其中粒子碰撞只检查一次,并且粒子不检查自身。可以在当前粒子之后启动嵌套循环(实际上是用已经检查过的索引来抵消索引),如下所示:

for( int i = 0; i < p.size()-1; i++){
    for(int j = i+1; j < p.size(); j++){

对于大量的粒子,这也有明显更快的好处。

也没有理由将计算的距离存储在数组中(除非您的代码在其他地方使用它)。在这里使用double类型就可以了。

编辑:

为了更清楚一点,我记录了两个数组的输出来演示。我在数组中使用了3个粒子。

原始循环

1比1(这是一个问题。检查粒子与自身的对比)
1比2
1比3
2比1这是个问题。这已经被检查过了)
)这是一个问题。检查粒子与自身的对比)
2比3
这是一个问题。这已经被检查过了)
)这是一个问题。这已经被检查过了)
)这是一个问题。检查粒子自身)

修改循环

1比2
1比3
2与3相比

如您所见,在修改后的循环中只检查了三次碰撞,并且没有双重碰撞。