簡體   English   中英

找到兩個3D點之間距離的有效方法

[英]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_horizo​​ntal是一個優化的地方

沒有沒有更好的方法。

可以優化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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM