Algorithm 网格中点与点之间距离的优化算法

Algorithm 网格中点与点之间距离的优化算法,algorithm,geometry,coordinates,discrete-mathematics,micro-optimization,Algorithm,Geometry,Coordinates,Discrete Mathematics,Micro Optimization,在像素网格中,我希望计算从一个选定像素到所有其他像素的欧几里德距离 这也可以被认为是在二维网格坐标系中的一个点和所有其他点之间找到欧氏距离 现在,简单的解决方案是在网格上迭代,并使用毕达哥拉斯加法(两个平方和的平方根)计算每个像素和所选像素之间的距离: for (int y = 0, x; y < gridHeight; ++y) { for (x = 0; x < gridWidth; ++x) { dist[x][y] = sqrt((chosenPixe

在像素网格中,我希望计算从一个选定像素到所有其他像素的欧几里德距离

这也可以被认为是在二维网格坐标系中的一个点和所有其他点之间找到欧氏距离

现在,简单的解决方案是在网格上迭代,并使用毕达哥拉斯加法(两个平方和的平方根)计算每个像素和所选像素之间的距离:

for (int y = 0, x; y < gridHeight; ++y) {
    for (x = 0; x < gridWidth; ++x) {
        dist[x][y] = sqrt((chosenPixelX - x)^2 + (chosenPixelY - y)^2);
    }
}
…对每个像素进行sqrt操作

我知道近似值,但我们能否进一步利用点/坐标位于网格上的事实,并以已知的方式(即x轴上的+1个单位)迭代,以滚动方式计算/近似欧氏距离,从而避免调用每个坐标的sqrt


示例:是否可以使用d1计算/近似d2?绿色表示所选像素。

因为您在网格上,所以只需计算每个网格点距离的绝对值->1,1==-1,-1=-1,1==1,-1。此外,由于对角对称性,配对中的匹配值也不需要计算->2,3==3,2==-2,3==等。最后,任何时候当计算值为0时,只需取另一个值->3,0==3

使用所有这些技巧,您可以减少至少87%的计算,甚至更多的平方根

更好的是,如果您事先知道网格的最大大小,并且能够提供足够的内存,则可以在编译时将所有这些预先计算为一个简单的二维查找。这就是我们过去如何进行正/余弦计算的方法-45度的查找数据和处理绝对值的对称性,如果abs后大于45度,则为90度


但是。。。从内存中进行所有这些比较和查找以获取要缓存的值是否更快,或者使用现代CPU在不需要查找的情况下并行计算多个数据段是否更快?我必须进行测试,但我会从更简单的迭代开始,而不是从所有这些技巧开始。

因为你在一个网格上,你只需要计算每个网格点距离的绝对值->1,1==-1,-1=-1,1==1,-1。此外,由于对角对称性,配对中的匹配值也不需要计算->2,3==3,2==-2,3==等。最后,任何时候当计算值为0时,只需取另一个值->3,0==3

使用所有这些技巧,您可以减少至少87%的计算,甚至更多的平方根

更好的是,如果您事先知道网格的最大大小,并且能够提供足够的内存,则可以在编译时将所有这些预先计算为一个简单的二维查找。这就是我们过去如何进行正/余弦计算的方法-45度的查找数据和处理绝对值的对称性,如果abs后大于45度,则为90度


但是。。。从内存中进行所有这些比较和查找以获取要缓存的值是否更快,或者使用现代CPU在不需要查找的情况下并行计算多个数据段是否更快?我必须进行测试,但我会从更简单的迭代开始,而不是从所有这些技巧开始。

SIMD的东西很快就把它吃光了。最糟糕的情况是找到距离的平方,然后立即执行一系列sqrt调用。此外,围绕水平轴、垂直轴和对角轴相对于起点的对称性-例如:d2下方和右侧的点是相同的。此外,水平/垂直距离不需要sqrt-只需减去坐标即可。网格通常具有合理的大小,因此值得预先计算所有可能的δx、δy的距离,并将其存储在表中。但是你要如何利用这些距离呢?SIMD的东西很快就把它吃光了。最糟糕的情况是找到距离的平方,然后立即执行一系列sqrt调用。此外,围绕水平轴、垂直轴和对角轴相对于起点的对称性-例如:d2下方和右侧的点是相同的。此外,水平/垂直距离不需要sqrt-只需减去坐标即可。网格通常具有合理的大小,因此值得预先计算所有可能的δx、δy的距离,并将其存储在表中。但是你打算如何利用这些距离??