[英]Efficient way of finding distance between two 3D points
我正在用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坐標。
謝謝
你需要實際的距離嗎? 您可以使用距離平方來確定它們是否相同,以及用於許多其他目的。 (保存在sqrt操作上)
如果我只是想確定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;
}
不,沒有更有效的方法來計算dist。 任何特殊情況下的治療px == qx等平均會慢一些。
是的,查看p和q是否相同的點的最快方法是比較x,y,z。 因為它們是浮點數,所以你不應該檢查==但允許你定義的一些有限的小差異。
您可以嘗試使用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計算diff:
__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]將填滿你的答案。
PS add_horizontal是一個優化的地方
沒有沒有更好的方法。
可以優化square_root
的實現。
如果您要比較兩個距離並想知道更長的距離,但不關心實際距離是什么,那么您可以簡單地完成平方根步驟並操縱您的距離仍然是平方的。 例如,這將適用於比較兩對點以確定它們是否是相同的距離。
您可能會發現這篇文章很有趣:
http://www.codemaestro.com/reviews/9
它描述了如何在Quake 3引擎中計算平方根,聲稱在某些CPU上它的運行速度是sqrt()函數的4倍。 不知道它現在是否能給你帶來C ++的性能提升 - 但仍然是一個有趣的讀物
請注意,使用sqrt(dx*dx+dy*dy+dz*dz)
,平方和可能會溢出。 hypot(dx, dy)
直接計算距離,沒有任何溢出的可能性。 我不確定最快的3d等效物,但是hypot(dx, hypot(dy, dz))
完成了這項工作並且也不會溢出。
Q2答案:如果點相同,則x1 = x2且y1 = y2,z1 = z2。
考慮到您將點存儲為float / double,您可能需要與某些epsilon進行比較。
有更快的方法來獲得近似距離,但沒有內置於標准庫中。 看看FlipCode上的這篇文章 ,它涵蓋了快速2D距離的方法。 它基本上將sqrt函數折疊為復合線性函數,可以快速計算,但不是100%准確。 然而,在現代機器上,這些天fpmath相當快,所以不要太早優化,你可能會發現你很好地采取你的簡單方法。
GNU科學庫定義了gsl_hypot3
,它可以准確計算問題第一部分所需的距離。 考慮到Darius的建議,有點矯枉過正在編譯整個事情,但也許還有其他你需要的東西。
就問題1而言,性能損失是平方根本身的計算。 使用成對坐標差的平方根計算距離的公式就是這樣。
我強烈建議閱讀John Carmack在他的Quake III引擎中使用的ID軟件的這個令人驚嘆的平方根實現。 這簡直就是魔術。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.