C++ 获取网格上最接近的点到点

C++ 获取网格上最接近的点到点,c++,algorithm,computational-geometry,C++,Algorithm,Computational Geometry,我有一个一维网格。它的间距是一个浮点。我有一个带浮点坐标的点。我需要找到它到最近网格点的距离。 例如: 0.12 | * |---------|---------|---------|---------|---------| 0 0.1 0.2 0.3 0.4 0.5 结果将是-0.02,因为最近的点在它后面。 但是如果是

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

            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;
float间距=。。。;
浮点=。。。;
而(点>=间距)点-=间距;
而(点<0)点+=间距;
如果(标准::abs(点间距)<点)点-=间距;

这是可行的,但我相信有一种方法可以避免循环,您应该使用以下方法对数字进行四舍五入:

float spacing = ...;
float point = ...;
(point > 0.0) ? floor(point + spacing/2) : ceil(point - spacing/2);
std::向量间距=。。。;
浮点=。。。;
浮动结果;
既然你说间距不是(线性的),我会缓存总和:

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::向量和(1,0.0);
浮点数和=0;

对于(inti=0;i这是我的第一次尝试,请注意,这根本没有经过测试

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;

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

leftBorder = spacing * floor(point/spacing);
rightBorder = leftBorder + spacing;
那么距离就很简单了:

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

更一般地说,对于任意间距、尺寸和距离度量(公制),您要查找的结构将是Voronoi图。

在他的示例中,它是线性的。@MooingDuck:它是线性的,而不是常数(它的参数)调用内部的间距是恒定的,调用之间的间距不是恒定的……在他对您答案的评论中,他说调用内部的间距是恒定的。@MooingDuck:不,他说它不是恒定的。@MooingDuck:我没有说它不是线性的,我只是说它不是始终为0.1。(它是一个参数)@Dani:我误解了这个评论。我的错。@Dani:我澄清了如何使用非常量间距进行此操作。地板和天花板四舍五入到最接近的整数,而不是最接近的步长值。感谢您的建议。我修改了变量以使其具有自我表达能力。我是否需要添加更多解释?自然语言的解释只会让您更满意答案更好,所以去做吧!我用自然语言加了一些句子:)
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;
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;