首先,我是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
的尝试不起作用!
答案 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意味着如果它们相交,它们将改变方向两次,每次将它们放回到相同的方向。因此,需要一些额外的逻辑来避免这种情况。