2012-02-02 26 views
13

distanza tra due punti:Il modo più veloce per calcolare la distanza tra due CGPoint?

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

C'è un modo per fare questo la matematica più velocemente in Objective-C?

EDIT: Penso di aver bisogno di chiarire sopra. Ho scritto la formula qui sopra solo per chiarire quale formula sto usando per calcolare la distanza.^non è pensato per rappresentare xor - volevo solo rappresentare la formula matematica senza usare alcuna funzione come pow o qualsiasi cosa, quindi intendevo usare^per "alzare al potere spento". Mi stavo chiedendo se qualcuno sa se utilizzare operatori bit a bit, o altrimenti scrivere codice in assembly darebbe una versione ottimizzata. Sto usando la formula in un'applicazione iPhone/iPad.

+1

più veloce di cosa? –

+0

Mi stavo chiedendo se qualcuno conosce il modo più veloce per eseguire questo tipo di calcoli.Normalmente vorrei solo scrivere la formula e usare pow o qualcosa del genere, ma non sono a conoscenza se usare *, o gli operatori bit a bit produrrebbero risultati più veloci. – xcoder

risposta

35

No, se hai bisogno della distanza esatta non puoi battere quella formula.

Sebbene sia chiaro^non è un operatore per quadrare un valore, ma un operatore bit che esegue xor.

avrete bisogno di qualcosa come

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

Se si può vivere con solo la piazza (che è utile quando si desidera solo per fare qualcosa di simile sorta dalla distanza, è possibile utilizzare il molto più efficiente

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

Questi saranno almeno altrettanto buono come prigioniero di guerra soluzione. nel peggiore dei casi, pow() si usa la pila ed essere meno efficiente, ma forse il compilatore lo trasforma in x * x per questo caso.

+1

+1 Puoi essere sicuro che 'pow' richiederà almeno un ordine di grandezza più lungo di' * ', e non penso che il compilatore possa ottimizzare' pow' perché non sa per certo che non ha è stato sostituito con una funzione completamente diversa chiamata 'pow'. –

+1

Inoltre, 'hypot (dx, dy)'. –

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

considerando x1, x2, y1, y2 sono float o double o intero.

+0

Non credo che una funzione di esponenziazione per scopi generici (pow) per calcolare un quadrato sia più veloce della semplice moltiplicazione. –

7

Su un Mac Intel Clang compilerà:

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

in un totale di 6 istruzioni per la matematica: sub, mul, sub, mul, aggiungere, sqrt; abbastanza difficile da battere. (sqrt è una singola istruzione, anche se richiede più cicli).

3

L'unica cosa che può essere migliorata qui è la funzione di calcolo della radice quadrata.

Ho provato queste due funzioni (che si trova in una Wikipedia article on square root computation) per calcolare i valori approssimativi di radice quadrata:

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; 
} 

Ma sul mio Core 2 Duo CPU Pentium non sembrano essere più veloce rispetto alla x87 Istruzione FPU FSQRT. Verifica se funzionano più velocemente dello standard sqrtf()/sqrt() sulla tua piattaforma e se la precisione è sufficiente.

8

Offrendo questa soluzione semplice e di qualità. Molto probabilmente non è più veloce di qualsiasi dato in precedenza, solo più corto. Io personalmente sto usando hypot.

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

Per il docs, questo si ritorna "La radice quadrata di (x^2 + y^2)."

Problemi correlati