我是c +的新手并且基于这个问题:Collision detection of huge number of circles我想实现单元格列表,这里也有描述:https://en.wikipedia.org/wiki/Cell_lists以便从碰撞检测算法中获得更好的性能。 围绕这个主题可能有很多不同的算法,但我想关注这个。
现在我正在计算2D区域上具有相同尺寸的n个球体之间的碰撞。 我将区域划分为形成网格的单元格。 网格是用于单元格位置的2D数组,3是用于存储当前在该网格单元格中的球体数量的向量。
std::array<std::array<std::vector<int>, cols>, rows> grid;
我可以通过计算得到每个球在网格中的位置:
row = x/cell_width;
col = y/cell_height;
然后我可以将球号添加到相应的单元格中:
grid[row][col].push_back(ball);
然后我检查每个网格单元格中是否有球。如果是的话,我加入来自实际和周围单元格的所有球,形成一个向量(网格球),并对该组中的碰撞进行粗暴检查。
for( int i = 1; i <rows; i = i + 1 ){
for( int j = 1; j <cols; j = j + 1 ){
if (grid[i][j].size()!=0){
gridballs=grid[i][j];
int nextx[]={1,1,0,-1,-1,-1,0,1};
int nexty[]={0,1,1,1,0,-1,-1,-1};
for( int k = 1; k <8; k = k + 1 ){
if (grid[i+nextx[k]][j+nexty[k]].size()!=0){
gridballs.insert(gridballs.end(), grid[i+nextx[k]][j+nexty[k]].begin(), grid[i+nextx[k]][j+nexty[k]].end());
}
}
collisioncheck (gridballs);
}
}
}
}
执行此操作时出现了以下问题:
比在2D阵列中使用矢量更好的结构是什么?网格中的所有内容总是会发生变化,我认为不断添加和重置向量需要花费大量时间?
通过每次都包括周围的细胞,多次检查很多细胞,我不会失去很多表现吗?有没有办法绕过这个或者我错过了什么?
确保我不会两次测试一对球体的有效方法是什么?
非常感谢您的帮助!
答案 0 :(得分:0)
首先,你的循环写得非常糟糕。而不是:
gridballs=grid[i][j];
int nextx[]={1,1,0,-1,-1,-1,0,1};
int nexty[]={0,1,1,1,0,-1,-1,-1};
for( int k = 1; k <8; k = k + 1 ){
if (grid[i+nextx[k]][j+nexty[k]].size()!=0){
gridballs.insert(gridballs.end(), grid[i+nextx[k]][j+nexty[k]].begin(), grid[i+nextx[k]][j+nexty[k]].end());
}
}
尝试:
balls.clear();
for (int dx=-1; dx<=1; dx++)
for (int dy=-1; dy<=1; dy++) {
const std::vector<int>& cell = grid[i+dx][j+dy];
balls.insert(balls.end(), cell.begin(), cell.end());
}
其次,使用++i
和++j
(或i++
和j++
)代替i = i + 1
和j = j + 1
。
关于你的问题,碰撞检测的良好结构是四叉树(在2d中)或八叉树(在3d中)。类似的东西:
class Quadtree {
public:
Quadtree(const vector<int>& vBalls, Quadtree* parent=NULL);
int size() const {return nBalls;}
bool empty() const {return nBalls == 0;}
bool IsInside(double x, double y, double r) const; // is the ball completely inside the square?
bool IsOutside(double x, double y, double r) const; // is the ball completely outside the square?
// ... other member functions
private:
double xMin, yMin, xMax, yMax; // all balls must be within this square
vector<int> vBigBalls; // balls which occupy more than one sub-square
vector<Quadtree> vSubsquares; // 4 subsquares
int nBalls; // total number of balls in the square and subsquares
Quadtree* parent; // not sure if you need this
}