找到两个3D点之间距离的有效方法

时间:2010-02-15 08:41:49

标签: c++ performance math

我正在用C ++编写代码,想要计算两点之间的距离。 问题1:

我有两个点P(x1,y1,z1)和Q(x2,y2,z2),其中x,y和z是浮点数/双精度数。

我想找到这两点之间的距离。一种方法是:

square_root(x_diff x_diff + y_diff y_diff + z_diff * z_diff)

但这可能不是最有效的方法。 (例如,math.h等中的更好的公式或现成的实用程序)

问题2:

如果我只想确定P和Q是否实际上是相同的点,是否有更好的方法?

我的输入是两个点的x,y和z坐标。

谢谢

11 个答案:

答案 0 :(得分:47)

你需要实际距离吗?您可以使用距离平方来确定它们是否相同,以及用于许多其他目的。 (保存在sqrt操作上)

答案 1 :(得分:15)

  

如果我只想确定P和Q是否实际上是相同的点,是否有更好的方法?

然后直接比较坐标!

bool areEqual(const Point& p1, const Point& p2) {
     return fabs(p1.x - p2.x) < EPSILON &&
            fabs(p1.y - p2.y) < EPSILON &&
            fabs(p1.z - p2.z) < EPSILON;
}

答案 2 :(得分:7)

不,没有更有效的方法来计算dist。任何特殊情况p.x == q.x等处理的平均速度都会较慢。

是的,查看p和q是否相同的点的最快方法是比较x,y,z。因为它们是浮点数,所以你不应该检查==但是允许你定义一些有限的小差异。

答案 3 :(得分:6)

您可以尝试使用SSE扩展。例如,您可以初始化两个向量A(x1,y1,z1)和B(x2,y2,z2):

_m128 A = _mm_set_ps(x1, y1, z1, 0.0f)
_m128 B = _mm_set_ps(x2, y2, z2, 0.0f)

然后使用_mm_sub_ps计算差异:

__m128 Diff = _mm_sub_ps(A, B)

接下来计算diff:

的sqr
__m128 Sqr = __mm_mul_ps(Diff, Diff)

最后:

__m128 Sum = add_horizontal(Sqr)
__m128 Res = _mm_sqrt_ss(Sum)

Res [0]将填满你的答案。

P.S。 add_horizo​​ntal是一个优化的地方

答案 4 :(得分:5)

没有没有更好的方法。

square_root的实施可能会得到优化。

如果您要比较两个距离并想知道更长的距离,但不关心实际距离是什么,那么您可以简单地完全依赖平方根步骤并操纵您仍然平方的距离。例如,这将适用于比较两对点以确定它们是否是相同的距离。

答案 5 :(得分:4)

您可能会发现这篇文章很有趣:

http://www.codemaestro.com/reviews/9

它描述了如何在Quake 3引擎中计算平方根,声称在某些CPU上它的运行速度是sqrt()函数的4倍。不确定它现在是否能给你带来C ++的性能提升 - 但仍然是一个有趣的阅读

答案 6 :(得分:4)

请注意,使用sqrt(dx*dx+dy*dy+dz*dz)时,平方和可能会溢出。 hypot(dx, dy)直接计算距离,没有任何溢出的可能性。我不确定最快的3d等价物,但是hypot(dx, hypot(dy, dz))完成了这项工作并且也不会溢出。

答案 7 :(得分:2)

Q2回答:如果点数相同,则x1 = x2,y1 = y2,z1 = z2。

考虑到你将点存储为float / double,你可能需要与某些epsilon进行比较。

答案 8 :(得分:1)

有更快的方法可以获得近似距离,但没有内置于标准库中。看看FlipCode上的this article,它涵盖了快速2D距离的方法。它基本上将sqrt函数折叠为复合线性函数,可以快速计算,但不是100%准确。然而,在现代机器上,这些天fpmath相当快,所以不要太早优化,你可能会发现你很好地采取你的简单方法。

答案 9 :(得分:1)

GNU Scientific Library定义gsl_hypot3,它可以准确计算问题第一部分所需的距离。鉴于Darius的建议,有点矫枉过正在编译整个事情,但也许还有其他你想要的东西。

答案 10 :(得分:0)

就问题1而言,性能损失是平方根本身的计算。使用成对坐标差的平方根计算距离的公式就是这样。

我强烈建议阅读John Carmack在他的Quake III引擎中使用的ID软件的A-M-A-Z-I-N-G平方根实现。这简直就是魔术。