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

Кватернион и нормализация

Я знаю, что кватернионы должны быть нормализованы, если я хочу повернуть вектор.

Но есть ли причины не автоматически нормализовать кватернион? А если есть, то какие операции кватернионов приводят к ненормированным кватернионам?

  • Умножение двух кватернионов?
  • Скалярное произведение?

Извините, если этот вопрос немного нечеткий. Я все еще пытаюсь обернуть голову вокруг кватернионов.

4b9b3361

Ответ 1

Любая операция, которая производит кватернион, должна быть нормализована, поскольку ошибки прецессии с плавающей запятой заставят ее не быть единичной длиной.

Я бы посоветовал против стандартных процедур, выполняющих нормализацию автоматически по соображениям производительности. Любой компетентный программист должен знать о проблемах точности и быть в состоянии нормализовать количество при необходимости - и не всегда необходимо иметь кватернион длины единицы.

То же самое верно для векторных операций.

Ответ 2

Запоздалый ответ; этот ответ для людей, которые сталкиваются с этим вопросом в будущем, а не для вопрошающего.

Я не согласен с двумя другими ответами, касающимися только нормализации кватерниона. Стандартные формулы для использования кватерниона для поворота/преобразования вектора или для генерации матрицы вращения/преобразования неявно предполагают, что кватернион нормирован. Ошибки, возникающие в результате использования ненормализованного кватерниона, пропорциональны квадрату величины кватерниона. Квадратичный рост ошибок - это то, чего лучше всего избегать.

Если вы часто нормализуетесь, вам не нужен квадратный корень. Приближение первого порядка работает довольно хорошо. Здесь то, что я использую для кватернионов, поскольку IEEE удваивается, несколько стилизован:

double qmagsq = quat.square_magnitude();
if (std::abs(1.0 - qmagsq) < 2.107342e-08) {
    quat.scale (2.0 / (1.0 + qmagsq));
}
else {
    quat.scale (1.0 / std::sqrt(qmagsq));
}

Обратите внимание, что я использую аппроксимацию первого порядка Паде 2.0/(1.0+qmagsq) первого порядка, а не расширение Тейлора первого порядка 0.5*(3.0-qmagsq) для оценки 1.0/std::sqrt(qmagsq). Это приближение, если оно верно, заменяет квадратный корень вызовом простым делением. Ключ должен найти, когда это приближение действительно, где находится волшебное число 2.107342e-08.

Почему аппликация Паде? Две причины. Первый заключается в том, что для значений qmagsq близких к одному, 1+qmagsq теряет меньше точности, чем 3-qmagsq. Другая заключается в том, что аппроксимация Паде разрешает ошибку в три раза по сравнению с расширением Тейлора. При значениях qmagsq между 0 и 2 ошибка в этом приближении меньше (1-qmagsq)^2/8. Магическое число 2.107342e-08 показывает, где эта ошибка больше, чем половина ULP для удваивания IEEE. Если вы предпринимаете разумные небольшие шаги, квадрат величины кватерниона всегда будет в этом пределе. Вы никогда не будете звонить в sqrt.

Единственное исключение из этой парадигмы "нормализовать всегда" может быть, если вы используете метод интеграции групп Ли для распространения кватернионов. Если вы не знаете, что это значит, вы, вероятно, используете эквивалент q(t+Δt) = q(t) + dq(t)/dt*Δt для распространения кватерниона. Вы все еще используете этот шаг Эйлера, даже если вы используете метод интеграции более высокого порядка, который не является интегратором группы Ли.

Ответ 3

Как ни странно, матрицы вращения здания - это одна операция, в которой нормализующие кватернионы НЕ нужны, экономя вас на одном sqrt:

M = [w*w+x*x-y*y-z*z, 2*(-w*z+x*y),    2*(w*y+x*z);
     2*(w*z+x*y),     w*w-x*x+y*y-z*z, 2*(-w*x+y*z);
     2*(-w*y+x*z),    2*(w*x+y*z),     w*w-x*x-y*y+z*z] / (w*w+x*x+y*y+z*z)

(в обозначениях MATLAB) для кватерниона w+x*i+y*j+z*k.

Более того, если вы работаете с однородными координатами и матрицами преобразования 4x4, вы также можете сэкономить некоторые операции деления: просто сделайте часть вращения 3x3, как если бы кватернион был нормализован, а затем поместил свою квадратную длину в (4,4) [CN00 ]:

M = [w*w+x*x-y*y-z*z, 2*(-w*z+x*y),    2*(w*y+x*z),     0;
     2*(w*z+x*y),     w*w-x*x+y*y-z*z, 2*(-w*x+y*z),    0;
     2*(-w*y+x*z),    2*(w*x+y*z),     w*w-x*x-y*y+z*z, 0;
     0,               0,               0,               w*w+x*x+y*y+z*z].

Умножить на матрицу перевода и т.д., Как обычно, для полного преобразования. Таким образом, вы можете сделать, например,

[xh yh zh wh]' = ... * OtherM * M * [xold yold zold 1]';
[xnew ynew znew] = [xh yh zh] / wh.

Конечно, нормализующие кватернионы по-прежнему рекомендуются (это может потребоваться и для других операций).

Ответ 4

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

Пусть q представляет собой матрицу 4 на 1 столбца кватернионов, а dq - ее производную по времени. Затем посылая dq + 0,5 (1-qq) q/tau на интегратор вместо dq и используя подходящую постоянную времени tau, будет непрерывно нормализовать qqq, представляет собой скалярное произведение.

Я смоделировал консервативный, артикулирующий механизм Брикарда, плавающий в свободном от гравитации пространстве на 3,6 миллиона секунд, что составляет почти 42 дня. Кватернионы представляли ориентацию плавающего базового тела. Полная энергия оставалась постоянной с точностью до одной части на миллион, используя постоянную времени tau 0,5 секунды. В численном интеграторе DE использовался абсолютный погрешность погрешности 10 ^ -12 и относительный погрешность погрешности нуля.

http://www.amazon.com/Computer-Solution-Ordinary-Differential-Equations/dp/0716704617/

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

Ответ 5

ваш вопрос неоднозначен, но если вам нужно нормализовать кватернион, это просто

q_normalized = q/square (норма (q))

с, q = q1 +q2i + q3 j +q4 k norm (q) = (q1) ^ 2 + (q2) ^ 2 + (q3) ^ 2) + (q4) ^ 4

если еще объясните мне свой вопрос

Ответ 6

Использование кватернионов NONunit может быть эффективным.

Только для нескольких операций требуется длина блока, например интерполяция.

Некоторые советы:

  1. Создание и преобразование в неединичные кватернионы могут быть более эффективными.
  2. Преобразование в матрицу из неединичного кватерниона по-прежнему быстро. Просто компенсируйте масштаб квадрата кватернионов.
  3. матрица преобразования в неединичную четверть быстрее.

Поэтому не требуется использовать только единичные кватернионы, это обычная практика. Для каждого варианта использования вы можете принять решение или не нормализовать его. Лично я предпочитаю использовать неединичные кватернионы.

ПРЕДУПРЕЖДЕНИЕ: часто, работая с блочными кватернионами, мы забываем о числовых ошибках. Например, преобразование из/в матричный кватернион и мысль о том, что он все еще делает большую численную нестабильность, масштабируется матрица, извлеченные кватернионы недопустимы. Вы можете легко провести такой эксперимент.