我正在用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坐标。
谢谢
答案 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_horizontal是一个优化的地方
答案 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平方根实现。这简直就是魔术。