获得最靠近网格点的点

时间:2011-12-01 18:34:24

标签: c++ algorithm computational-geometry

我有一个一维的网格。它的间距是一个浮点。我有一个浮点坐标点。我需要找到距离最近的网格点的距离 例如:

            0.12
             |
             *
 |---------|---------|---------|---------|---------|
 0        0.1       0.2       0.3       0.4       0.5

结果将是-0.02,因为最接近的点就在它后面 但是,如果它是

                -0.66
                  |
                  *
 |---------|---------|---------|---------|---------|
-1       -0.8      -0.6      -0.4      -0.2        0

结果将为0.06。正如你可以看到它的浮点数并且可以是负数 我尝试了以下方法:

float spacing = ...;
float point = ...;

while(point >= spacing) point -= spacing;
while(point < 0) point += spacing;

if(std::abs(point - spacing) < point) point -= spacing;

它有效,但我确信有一种没有循环的方法

5 个答案:

答案 0 :(得分:6)

让我们首先计算左右最近的点,如下所示:

leftBorder = spacing * floor(point/spacing);
rightBorder = leftBorder + spacing;

然后距离很简单:

if ((point - leftBorder) < (rightBorder - point))
    distance = leftBorder - point;
else
    distance = rightBorder - point;

请注意,我们可以通过天花板找到最近的点:

rightBorder = spacing * ceil(point/spacing);
leftBorder = rightBorder - spacing;

答案 1 :(得分:2)

std::vector<float> spacing = ...;
float point = ...;
float result;

既然你说间距不是(线性的),我会缓存总和:

std::vector<float> sums(1, 0.0);
float sum=0;
for(int i=0; i<spacing.size(); ++i)
    sums.push_back(sum+=spacing[i]);
//This only needs doing once.
//sums needs to be in increasing order.  

然后进行二分查找以找到左边的点:

std::vector<float>::iterator iter;
iter = std::lower_bound(sums.begin(), sums.end(), point);

然后从那里找到结果:

if (iter+1 == sums.end())
    return point-*iter;
else {
    float midpoint = (*iter + *(iter+1))/2;
    if (point < midpoint)
        result = point - *iter;
    else
        result = *(iter+1) - point;
}

[编辑]我不觉得傻。你说间距不是恒定的。我认为这不是线性的。但是,您的示例代码线性的,而不是编译时常量。我的错。我会把这个答案作为一个更通用的解决方案,尽管你的(线性)问题可以更快地解决。

答案 2 :(得分:2)

这是我的第一次脸红尝试,请注意,这根本没有测试过。

float remainder = fmod(point, spacing); // This is the fractional difference of the spaces
int num_spaces = point/spacing;  // This is the number of "spaces" down you are, rounded down


// If our fractional part is greater than half of the space length, increase the number of spaces.
// Not sure what you want to do when the point is equidistant to both grid points
if(remainder > .5 * spacing) 
{
  ++num_spaces;
}

float closest_value = num_spaces*spacing;
float distance = closest_value - point;

答案 3 :(得分:0)

您应该使用以下方法对数字进行舍入:

float spacing = ...;
float point = ...;
(point > 0.0) ? floor(point + spacing/2) : ceil(point - spacing/2);

答案 4 :(得分:0)

更常见的是,对于任意间距,尺寸和距离度量(度量),您正在寻找的结构将是Voronoi图。