Эффективный способ уменьшить векторную величину на определенную длину? - PullRequest
9 голосов
/ 09 января 2012

Допустим, у меня есть произвольный вектор А. Каков наиболее эффективный способ уменьшения величины этих векторов на произвольную величину?

Мой текущий метод выглядит следующим образом:

Vector shortenLength(Vector A, float reductionLength) {

    Vector B = A;
    B.normalize();
    B *= reductionLength;
    return A - B;

}

Есть ли более эффективный способ сделать это? Возможно удаление квадратного корня, необходимого для нормализации B ...

Ответы [ 2 ]

10 голосов
/ 09 января 2012

Так что, если я вас правильно понимаю, у вас есть вектор A, и вам нужен еще один вектор, который указывает в том же направлении, что и A, но короче на reductionLength, верно?

интерфейс Vector имеет что-то вроде функции-члена "length" (возвращающей длину вектора)?Тогда я думаю, что следующее должно быть более эффективным:

Vector shortenLength(Vector A, float reductionLength) 
{
    Vector B = A;
    B *= (1 - reduction_length/A.length());
    return B;
}
6 голосов
/ 09 января 2012

Если вы собираетесь масштабировать вектор путем умножения его на скалярное значение, вы должны не нормализовать. Не по соображениям эффективности; потому что результат не тот, который вы, вероятно, хотите.

Допустим, у вас есть вектор, который выглядит следующим образом:

v = (3, 4)

Его величина sqrt(3^2 + 4^2) = 5. Итак, давайте нормализуем это:

n = (0.6, 0.8)

Этот вектор имеет величину 1; это единичный вектор.

Итак, если вы «укоротите» каждый из них в 0,5 раза, что вы получите?

shortened v = (3, 4) * 0.5 = (1.5, 2.0)

Теперь давайте нормализуем его по величине sqrt (6.25):

normalized(shortened v) = (1.5/2.5, 2/2.5) = (0.6, 0.8)

Если мы сделаем то же самое с вектором единицы измерения:

shortened(normalized v) = (0.6, 0.8) * 0.5 = (0.3, 0.4)

Это совсем не одно и то же. Ваш метод делает две вещи, и они не коммутативны.

...