2011-04-25 59 views
2

首先,我对C++很陌生!所以我已经有了一个标准的2d空间元素列表,我想做一些基本的碰撞检测。我的第一个想法(来自大多数Java背景......)是将每个对象与其他对象进行比较,调用一个函数来检查每个对或对象上的交集。这在Java中很简单,将ArrayList的第一项与第二项,第三项等进行比较,然后将第二项与第三项,第四项等进行比较。这是我采用的方法问题在C++中,但我使用的是一个迭代器(而不是象我在Java中那样直接访问元素),但是迭代器可以线性使用,对吧?所以直接访问是不合适的。用于碰撞检测的C++双迭代器循环

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

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不起作用!

+2

只是一个建议,当处理迭代器时,更喜欢前缀++而不是后缀(性能明智),所以在你的循环中它应该是:++ q和++ p – snoofkin 2011-04-25 19:58:21

+0

注明以备将来使用! – jackbot 2011-04-25 20:08:53

+0

还有一个建议:如果你想使用索引而不是interator,考虑'std :: vector'而不是'std :: list.' – 2011-04-25 20:14:04

回答

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(); 
     } 
    } 
} 
+0

因为p和q是指针,你可以比较它们(例如“if(p == q)继续;“跳过比较本身) – 2011-04-25 20:04:30

+0

伟大,非常有意义。我的isIntersecting()函数需要一个Box类型作为参数,我如何从列表中获取实际元素,并按照我的示例传递它q通过迭代器 – jackbot 2011-04-25 20:05:27

+0

“* q”应该为您提供迭代器指向的框至。 – Arelius 2011-04-25 20:08:41

-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意思是,如果他们不相交他们会改变方向两次,每次都将它们放回相同的方向。所以需要一些额外的逻辑来避免这种情况。

+1

-1:'int p' ...'p-> isIntersecting'?你认为'p'是什么类型? – 2011-04-25 20:04:52

+0

这是行不通的,mBoxes是一个Box元素的链表,你已经做了p和q整数,他们没有你调用的方法,而且你不能索引到mBoxes,因为链表是可迭代的,不可索引。 – Arelius 2011-04-25 20:06:51

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 ++应该简单地跳过当前元素,所以你不要对自己比较的项目。