Подтвердить что ты не робот

Самый быстрый способ рассчитать расстояние между двумя CGPoints?

Расстояние между двумя точками:

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

Есть ли способ сделать эту математику быстрее в objective-C?

РЕДАКТОР: Я думаю, что мне нужно прояснить выше. Я написал формулу выше, чтобы уточнить, какую формулу я использую, чтобы вычислить расстояние. ^ не предназначен для представления xor - я просто хотел представить математическую формулу без использования каких-либо функций, таких как pow или что-нибудь еще, поэтому я хотел использовать ^ для "повышения мощности". Мне было интересно, знает ли кто-нибудь, если использовать побитовые операторы или иначе писать код в сборке, даст оптимизированную версию. Я использую формулу в приложении iPhone/iPad.

4b9b3361

Ответ 1

Нет, если вам нужно точное расстояние, вы не можете победить эту формулу.

Хотя ясно, что ^ не является оператором для квадратизации значения, а является битовым оператором, который делает 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. В худшем случае pow() будет использовать стек и быть менее эффективным, но, возможно, ваш компилятор превратит его в x * x для этого случая.

Ответ 2

На Intel Mac Clang будет компилироваться:

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

в общей сложности 6 инструкций для математики: sub, mul, sub, mul, add, sqrt; довольно сложно победить. (sqrt - это одна команда, хотя требуется несколько циклов).

Ответ 3

Просто предлагая это как простое, приятное решение. Скорее всего, это не так быстро, как раньше, но короче. Я лично использую hypot.

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

В docs это вернет вам "Квадратный корень из (x ^ 2 + y ^ 2)".

Ответ 4

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

учитывая x1, x2, y1, y2: float или double или integer.

Ответ 5

О единственном, что можно улучшить здесь, - это функция вычисления квадратного корня.

Я пробовал эти две функции (найти в статью Википедии о вычислении квадратного корня) для вычисления приблизительных значений квадратного корня:

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

Но на моем Core 2 Duo Pentium CPU они, похоже, не быстрее, чем инструкция x90 FPU FSQRT. Посмотрите, работают ли они быстрее, чем стандартный sqrtf()/sqrt() на вашей платформе, и если достаточная точность.