2012-02-02 127 views
13

两点之间的距离:最快的方法来计算两个CGPoints之间的距离?

sqrt((x1-x2)^2 + (y1-y2)^2) 

有没有办法在Objective-C这样做数学更快?

编辑:我想我需要澄清以上。我写了上面的公式来澄清我用什么公式计算距离。 ^并不是要表示异或 - 我只是想表示数学公式而不使用像pow或其他任何函数,所以我打算使用^来“提升电源关闭”。我想知道是否有人知道如果使用按位运算符,或者在程序集中编写代码会给出优化版本。我在iPhone/iPad应用程序中使用公式。

+1

比什么快? – 2012-02-02 12:11:00

+0

我只是想知道如果有人知道执行这种计算的最快方法。通常我只是写出公式并使用pow或其他东西,但我不知道使用*还是使用按位运算符会产生更快的结果。 – xcoder 2012-02-03 04:32:21

回答

35

不,如果您需要准确的距离,您无法击败该公式。

虽然要清楚^不是用于平方值的运算符,而是用于执行xor的位运算符。

你会需要像

double dx = (x2-x1); 
double dy = (y2-y1); 
double dist = sqrt(dx*dx + dy*dy); 

如果你可以只用方形生活(这是有用的,当你只是想这样做的距离排序,你可以用更有效的

double dx = (x2-x1); 
double dy = (y2-y1); 
double dist = dx*dx + dy*dy; 

这将至少为解决战俘一样好。在最坏的情况,POW()将使用堆栈和效率较低,但也许你的编译器把它变成X * X这种情况。

+1

+1你可以确定'pow'至少比'*'长一个数量级,我不认为编译器可以优化'pow',因为它不能确定它没有被一个完全不同的称为'pow'的函数取代。 – 2012-02-03 00:54:50

+1

另外,'hypot(dx,dy)'。 – 2014-08-13 13:40:32

3
double dist = sqrt (pow((x1-x2), 2) + pow((y1-y2), 2)); 

考虑x1, x2, y1, y2floatdouble或整数。

+0

我不认为通用指数函数(pow)计算正方形比简单乘法要快。 – 2012-02-03 05:25:49

7

在Intel的Mac锵将编译:

double distance = ({double d1 = x1 - x2, d2 = y1 - y2; sqrt(d1 * d1 + d2 * d2); }); 

成总计6个指令的数学:子,MUL,子,MUL,添加,SQRT;很难打败。 (sqrt是单个指令,但需要多个周期)。

3

关于这里可以改进的唯一的东西是平方根计算函数。

我已经试过这两个功能(在Wikipedia article on square root computation找到)来计算近似平方根值:

float fsqrt(float x) 
{ 
    float xhalf = 0.5f * x; 
    union 
    { 
    float x; 
    int i; 
    } u; 

    u.x = x; 
    u.i = 0x5f3759df - (u.i >> 1); 
    x *= u.x * (1.5f - xhalf * u.x * u.x); 

    return x; 
} 

float fsqrt2(float z) 
{ 
    union 
    { 
     int tmp; 
     float f; 
    } u; 

    u.f = z; 

    /* 
    * To justify the following code, prove that 
    * 
    * ((((val_int/2^m) - b)/2) + b) * 2^m = ((val_int - 2^m)/2) + ((b + 1)/2) * 2^m) 
    * 
    * where 
    * 
    * val_int = u.tmp 
    * b = exponent bias 
    * m = number of mantissa bits 
    * 
    * . 
    */ 

    u.tmp -= 1 << 23; /* Subtract 2^m. */ 
    u.tmp >>= 1; /* Divide by 2. */ 
    u.tmp += 1 << 29; /* Add ((b + 1)/2) * 2^m. */ 

    return u.f; 
} 

但在我的酷睿2奔腾CPU,他们似乎并不比更快的x87 FPU FSQRT指令。看看他们的工作是否比平台上的标准sqrtf()/sqrt()快,并且准确度足够。

8

只是提供这个作为一个简单,漂亮的解决方案。这很可能不会比以前给出的更快,只是更短。我个人正在使用hypot

double dist = hypot((x1-x2), (y1-y2)); 

根据docs,这会返回“平方根(x^2 + y^2)”。

相关问题