用于碰撞检测的C ++双迭代器循环

时间:2011-04-25 19:51:49

标签: c++ iterator collision-detection

首先,我是C ++的新手!所以我有一个标准的对象列表,表示二维空间中的元素,我想做一些基本的碰撞检测。我的第一个想法(来自大多数Java背景......)是将每个对象与另一个对象进行比较,调用一个函数来检查每对或多个对象的交集。这在Java中很简单,取出ArrayList的第一项,将它与第二项,第三项等进行比较,然后取第二项,将它与第三项,第四项等进行比较。这是我采用的方法。 C ++中的问题,但我使用的是迭代器(而不是像我在Java中那样使用直接元素访问),但是迭代器应该是线性使用的,对吧?所以直接访问是不合适的。

所以我的问题是如何执行此算法?我也有理由相信这不是做(非常基本的)碰撞检测的最佳方法,所以对此的任何建议也会受到欢迎。这是我的(非工作)代码。

for (list<Box>::iterator p = mBoxes.begin(); p != mBoxes.end(); p++) {
    for (list<Box>::iterator q = mBoxes.begin() + p); q != mBoxes.end(); q++) {
        if (p->isIntersecting(q)) {
            p->changeDirection();
            q->changeDirection();
        }
    }
}

这应该说明我正在尝试的方法,但当然我对mBoxes.begin() + p的尝试不起作用!

3 个答案:

答案 0 :(得分:5)

编辑:回复多条评论。

for (list<Box>::iterator p = mBoxes.begin(); p != mBoxes.end(); ++p) {
    for (list<Box>::iterator q = p); q != mBoxes.end(); ++q) {
        if (p==q) continue;
        if (p->isIntersecting(*q)) {
            p->changeDirection();
            q->changeDirection();
        }
    }
}

答案 1 :(得分:1)

列表类是一个链表,你不能直接索引它。此外,迭代器不是索引,+只是没有任何意义。

但是,从理论上讲,你应该能够复制迭代器,如果你将q = mboxes.begin()+ p改为q = p,它应该将q设置为指向p的相同位置的迭代器,并且这可能只是解决你的问题。

for (list<Box>::iterator p = mBoxes.begin(); p != mBoxes.end(); p++) {
  for (list<Box>::iterator q = p, q++; q != mBoxes.end(); q++) {
    if (p->isIntersecting(q)) {
        p->changeDirection();
        q->changeDirection();
    }
  }
}

q ++应该只是跳过当前元素,因此你不要将项目与自身进行比较。

答案 2 :(得分:-1)

这样的事情应该有效:

for (int p = 0; p < mBoxes.size(); ++p)
{
    for (int q = 0; q < mBoxes.size(); ++q)
    {
        if (p == q)
        {
            // don't compare for collision against itself
            continue;
        }
        if (mBoxes[p]->isIntersecting(mBoxes[q]))
        {
            mBoxes[p]->changeDirection();
            mBoxes[q]->changeDirection();
        }
    }
}

然而,有一个问题是,当你迭代时,你会比较p相交q和q相交p意味着如果它们相交,它们将改变方向两次,每次将它们放回到相同的方向。因此,需要一些额外的逻辑来避免这种情况。