Увы, продолжаю обнаруживать прорехи в своём "талмуде", которые надо заделывать. Впору делать ставки, что появится раньше, часть 11 ликбеза, или Half Life 3...
Уже несколько раз, в главах 6, а также с 8 по 10, мы довольно лихо оценивали точность тех или иных приближенных формул, и у нас даже что-то получалось, но лишь потому, что у нас оказывался примитивный частный случай, когда у двух кватернионов совпадала ось поворота, так что оставалось лишь сравнить угол поворота.
Увы, так не может продолжаться вечно, поэтому пора разобраться в вопросе: а что такое точность задания поворота? Что для нас важнее - правильно задать ось поворота, или величину угла? Говоря языком математиков, нужно ввести метрику, «расстояние» между различными поворотами.
Это можно сделать разными способами, мы покажем один из наиболее очевидных, но в то же время полезных в практическом плане, поскольку введённая метрика будет выражать максимально возможную ошибку, которая может возникнуть при повороте единичного вектора, когда вместо одного («истинного») поворота мы применим другой («вычисленный»).
Давайте абстрагируемся от способа представления поворота (матрица, углы Эйлера, кватернионы или что-то ещё), просто скажем, что поворот - это линейное преобразование, применяемое к трёхмерным векторам. Назовём два поворота, с которыми будем иметь дело, R1 и R2, от слова Rotation...
Возьмём некоторый единичный вектор . Повернём его с помощью наших преобразований:
Величиной рассогласования можно назначить модуль их разности:
(5½.1)
Метрикой, расстоянием между поворотами, назовём максимальное рассогласование, которое может получиться:
Векторы произвольной длины нас не очень интересуют, потому что рассогласование будет попросту пропорционально длине вектора, ничего не говоря о повороте.
Преобразуем выражение (5½.1), учитывая, что повороты не изменяют длину вектора, и что у каждого поворота R есть обратный, R-1, такой, что RR-1=R-1R=1:
- это тоже поворот, образованный композицией поворота R1 и поворота, обратному к R2. Нам хочется найти такой вектор , который максимально поменяется от поворота . К примеру, если взять вектор, идущий вдоль оси поворота, он и вовсе не поменяется, и получим . А лучшим выбором станет любой вектор, перпендикулярный оси поворота.
Вот теперь настала пора применить кватернионы: именно в такой записи легко узнать ось и величину поворота. Пусть кватернион Λ=λ0+λ1i+λ2j+λ3k выражает поворот R1, а кватернион Μ=μ0+μ1i+μ2j+μ3k - поворот R2. Найдём кватернион Ν=ν0+ν1i+ν2j+ν3k, соответствующий , не забывая, что кватернионы поворота имеют единичную норму:
Выпишем, чему равна скалярная часть Ν. Она складывается из произведения двух скалярных частей и из скалярного произведения векторных частей, взятого со знаком «минус». Но поскольку один из кватернионов уже взят сопряженный, то минус на минус даёт плюс, и мы получаем: ν0=μ0λ0+μ1λ1+μ2λ2+μ3λ3, А это ни что иное, как скалярное произведение кватернионов, если рассматривать их как четырёхмерные векторы. Давайте введём соответствующую операцию:
Также, учитывая единичную норму кватернионов, мы можем вывести следующее выражение (по сути, мы тут обращаемся с кватернионами, как с четырёхмерными векторами, что ничуть не противоречит предыдущим определениям): |Λ-Μ|2=|Λ|2-2(Λ,Μ)+|Μ|2=2-2(Λ,Μ),
Или
Теперь вспомним, как кватернион поворота записывается через ось поворота и его величину:
Следовательно,
Из рисунка выше, мы можем выразить d(R1, R2) через угол поворота φ:
Наконец, подставим сюда скалярную компоненту кватерниона Ν:
Итак,
Это и есть ответ. Когда два поворота достаточно близки друг к другу, правым множителем можно пренебречь, и мы приходим к совсем простому выражению:
Это ещё одно положительное качество кватернионов - кватернионы близких поворотов и расположены близко. Сравнивать повороты в углах Эйлера-Крылова гораздо труднее. Разница в 1 градус по долготе отвечает за дистанцию ≈110 км на экваторе, и всего за 2 км, если точка находится на 89 градусе широты (не важно, северной или южной).
Ну и в целом такая "равномерная" метрика - вещь радостная. Это значит, что все кватернионы, что мы можем закодировать в числах с фиксированной точкой, лягут равномерной "сеткой" по всем возможным поворотам, не образовывая ни больших прорех, ни "кучностей", какие случаются в других способах описания поворотов.
К примеру, если для записи каждой компоненты кватерниона используется 16-битное число в дополнительном коде с фиксированной точкой формата 1.15 (один бит перед точкой, 15 - после), то наибольшая ошибка в каждой компоненте составит половину цены младшего разряда, а именно: 1,5×10-5. В итоге максимальное значение ошибки составит:
Для малых значений, можно считать, что d() - это угол в радианах. В нашем случае это около 12 угловых секунд - такова максимальная ошибка, если на каждый компонент выделять по 16 бит. Если использовать 32 бита (точно так же, дополнительный код, фиксированная точка 1.31), ошибка составит 2×10-4 угловой секунды - такой точности достаточно для большинства применений. (Честно говоря, автору вообще сложно придумать ситуацию, когда такой точности окажется недостаточно).
Множитель с квадратным корнем «разбирается» с тем фактом, что один поворот может описываться двумя различными кватернионами, например, нулевой поворот может быть выражен кватернионами 1 и -1. Разность между ними: 2, равно как и модуль разности. Найдём расстояние:
Несложно увидеть, что мы получим нулевое значение для любых двух кватернионов, отличающихся лишь знаком. Кроме того, максимальное расстояние, равное 2 (то есть поворот на 180°) достигается, когда
А при дальнейшем увеличении нормы разности, расстояние снова начинает уменьшаться.
Строго говоря, нашу функцию d(Λ,Μ) нельзя называть метрикой для кватернионов, поскольку не выполняется свойство
Другие свойства метрики здесь выполняются, а также выполняется более «слабое» условие
Функцию с такими свойствами математики называют псевдометрикой.