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

mem*_*emC 17 c++ math performance

我正在用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坐标.

谢谢

Jam*_*mes 47

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

  • 这是比较的正确答案 - 以及您认为需要距离的许多其他矢量操作.使用距离平方!例如,不是写'sqrt(dx*dx + dy*dy + dz*dz)<epsilon`而是写'dx*dx + dy*dy + dz*dz <epsilonsquared`.在数学上等效,并且更快. (14认同)

Meh*_*ari 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;
}
Run Code Online (Sandbox Code Playgroud)

  • 你正在使用一个'EPSILON`大小的立方体来确定接近度.合理,但更快检查`(fabs(p1.x - p2.x)+ fabs(p1.y - p2.y)+ fabs(p1.z - p2.xz))<EPSILON_3D` - 单一比较.(用'EPSILON <= EPSILON_3D <= 3*EPSILON`) (5认同)
  • 不,"精度"仅由"p1"周围的体积大小决定,被认为等于"p1".我们的测试都使用了一个立方体,我的测试只是旋转.通过适当选择EPSILON_3D(`sqrt(3)*EPSILON` IIRC)可以获得完全相同的盒子大小,因此精度完全相同.至于速度; 如果你不相信它,请测试它. (3认同)

小智 7

不,没有更有效的方法来计算dist.任何特殊情况下的治疗px == qx等平均会慢一些.

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


shu*_*lov 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)
Run Code Online (Sandbox Code Playgroud)

然后使用_mm_sub_ps计算diff:

__m128 Diff = _mm_sub_ps(A, B)
Run Code Online (Sandbox Code Playgroud)

接下来计算diff的sqr:

__m128 Sqr = __mm_mul_ps(Diff, Diff)
Run Code Online (Sandbox Code Playgroud)

最后:

__m128 Sum = add_horizontal(Sqr)
__m128 Res = _mm_sqrt_ss(Sum)
Run Code Online (Sandbox Code Playgroud)

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

PS add_horizo​​ntal是一个优化的地方


Wil*_*ill 5

没有没有更好的方法.

square_root可能会优化实施.

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