这个问题更多的是关于算法和函数的正确使用而不是实际的代码。
在我的代码中,我使用map来模拟盒子。地图元素由vector<int>
作为键,set<shared_ptr<foo> >
作为值。
我正在做一个嵌套循环来遍历所有框:
mit1 = boxes.begin(); //mit1 is an appropriate iterator
int edge = 10;//represnd periodic boundary conditions
while (mit1 != boxes.end()){
vector<t> = mit1->first;
mit2 = mit1++;
while (mit2 != boxes.end()){
vector<int> u = (mit2++)->first;
bool good = true;
for (int i = 0; i < 3 && good; i++){
u[i] = (int)fabs(u[i] - t[i]);
good = u[i] == 0 || u[i] == 1 || u[i] == edge;
}
if (!good) continue;
}
}
我关心的是整个嵌套循环以及for
循环。
您是否认为使用函数计算所有相邻框更有效?你知道有什么更好的方法来进行for循环测试吗?
答案 0 :(得分:4)
与每次碰撞检测相同的建议:使用一些算法或数据结构,允许您按照空间距离预先过滤候选,并允许在O(n)中进行预过滤。想到一个四叉树,或粗粒度的空间地图。
编辑:为了使整个想法更清晰一些,请考虑以下算法:在3D空间中有N个粒子,并且想要找出哪个粒子彼此距离D比距离D更近。您构建一个3D数组,每个bin表示目标空间的立方体积,每个体积必须至少为D的大小。要查找可能比D更接近给定粒子X的所有粒子,您需要确定阵列单元格当前X所在的Ax,并选择Ax和所有周围单元格中的所有粒子。您只需要检查这个小子集是否存在冲突。
当使用M个阵列单元时,整个距离检查的平均情况计算复杂度现在是O(N * N / M)而不是O(N ^ 2),但是以O(M ^ 2)为代价空间。
如果目标空间无界,请使用四叉树(2D)或八叉树(3D)。
答案 1 :(得分:1)
这是一般碰撞/思维问题的简化版本。当你有一堆物体时,这些问题变得特别讨厌,每个物体由许多多边形面描述。对于这些问题,没有一种适合所有解决方案。有很多启发式方法可以帮助解决这个问题。其中一些:
使用边界球体和边界框。一对球体之间的距离比一对盒子之间的距离更容易计算,并且一对边界球体之间的距离决不会超过一对边界框之间的距离。这使您可以相当快地排除大量的计算。
使用对象层次结构。如果对象A,B,C和D总是彼此非常接近,那么创建包含A,B,C和D的元对象通常是有用的。如果您可以排除将此元对象视为候选对象只是排除了考虑作为候选人的任何对象。
如果对象移动缓慢,则下一步的最近邻居通常是当前步骤中的最近邻居。从这开始作为第一个猜测,然后搜索附近的其他物体,然后进一步到国外。最终(通常比较晚)你将排除所有剩余的物体。
答案 2 :(得分:0)
取决于您的计划正在做什么......
但是当盒子移动时可以计算距离。 然后它优化了一些(如果不是所有的盒子)都在移动。