我为点创建了一个最小距离过滤器。 该函数采用点流(x1,y1,x2,y2 ......)并删除相应的点。
void minDistanceFilter(vector<float> &points, float distance = 0.0)
{
float p0x, p0y;
float dx, dy, dsq;
float mdsq = distance*distance; // minimum distance square
unsigned i, j, n = points.size();
for(i=0; i<n; ++i)
{
p0x = points[i];
p0y = points[i+1];
for(j=0; j<n; j+=2)
{
//if (i == j) continue; // discard itself (seems like it slows down the algorithm)
dx = p0x - points[j]; // delta x (p0x - p1x)
dy = p0y - points[j+1]; // delta y (p0y - p1y)
dsq = dx*dx + dy*dy; // distance square
if (dsq < mdsq)
{
auto del = points.begin() + j;
points.erase(del,del+3);
n = points.size(); // update n
j -= 2; // decrement j
}
}
}
}
唯一的问题是非常缓慢,因为它针对所有点(n ^ 2)测试所有点。
如何改进?
答案 0 :(得分:2)
查找范围树,例如en.wikipedia.org/wiki/Range_tree。您可以使用此结构存储二维点,并快速查找查询矩形内的所有点。由于你想在点(a,b)的某个距离d内找到点,你的查询矩形需要是[ad,a + d] x [bd,b + d]然后你测试里面找到的任何点矩形,以确保它们实际上在(a,b)的距离d内。范围树可以在O(n log n)时间和空间中构建,范围查询需要O(log n + k)时间,其中k是矩形中找到的点数。似乎是您的问题的最佳选择。
答案 1 :(得分:2)
kd-trees或range trees可以用于解决您的问题。但是,如果您想从头开始编写代码并希望更简单,那么您可以使用哈希表结构。对于每个点(a,b),使用密钥(圆形(a / d),圆形(b / d))进行散列并将所有具有相同密钥的点存储在列表中。然后,对于哈希表中的每个键(m,n),将列表中的所有点与具有键(m',n')的点列表进行比较,对于(m',n')的所有9个选项,其中m '= m +( - 1或0或1)并且n'= n +( - 1或0或1)。这些是可以在具有键(m,n)的点的距离d内的唯一点。与kd树或范围树相比的缺点是,对于给定点,您有效地在边长3 * d的正方形内搜索可能具有距离d或更小的点,而不是在边长的正方形内搜索2 * d这是你使用kd树或范围树时会得到的。但是如果你从头开始编码,这就更容易编码;如果你只有一个你关心所有点的通用距离d,那么kd-trees和范围树也有点矫枉过正。