И ещё один кусочек "рукописи", который я дописал в тот момент, когда начал в ЖЖ выкладывать интегрирование угловых скоростей (части 7 - 10), и вклинивать туда "чужеродный элемент" не хотелось. А сейчас вроде даже логично...
Кватернион поворота по заданной оси, наиболее точно совмещающий два направления
Данная задача возникает при моделировании работы датчика инфракрасной вертикали в связке с солнечным датчиком и похожих систем (например, солнечно-звездные датчики времён Королёва), где первоначально происходит наведение на первый объект, а затем начинается вращение вокруг линии визирования на этот объект, пока второй объектив не наведётся на второй объект.
В общем случае, у нас есть два направления, на которые мы хотим навестись одновременно, при этом важность их различна. Мы должны выдерживать второе направление лишь до тех пор, пока это не вредит наведению на первое. К примеру, не страшно, если спутник ГЛОНАСС получит на 10% меньше мощности на солнечные батареи, из-за падения солнечных лучей под углом 25° к нормали солнечных батарей (они на это рассчитаны), а вот если диаграмма направленности передатчиков навигационного сигнала уползёт от Земли на 25°, кого-то точно уволят!
Пусть - единичный вектор направления на первый объект, - текущее направление второго объектива, - направление на второй объект. Мы хотим:
1. Найти угол φ, на который надо произвести поворот вокруг оси , чтобы вектор (повёрнутый ) максимально точно совместился с ; 2. Записать кватернион Λ соответствующего поворота.
Мы знаем ось поворота: , запишем кватернион поворота:
(8.1)
Угол пока неизвестен. Повернём по формуле (6.9) (из части 5):
Применив тригонометрические формулы для двойных углов, получим:
Возьмём скалярное произведение как меру близости двух векторов:
Запишем его как функцию от угла , максимум которой надо найти:
Слагаемое, не зависящее от , не оказывает влияния на результат. По сути, мы должны найти, когда достигается максимум функции
,
где
Поделим и умножим на одно и то же число:
Далее, мы можем сделать замену
и записать функцию следующим образом:
Данная функция достигнет максимума, если , или (с точностью до ). Наконец, мы можем записать:
(8.2)
Отметим интересный частный случай: все векторы лежат в одной плоскости. Тогда , и может принимать значения 0 или 180°. Всё верно: если вектор уже лежит в правильной плоскости, то уходить с неё не надо, разве что «зеркально отразиться» от вектора , если это поможет.
Остаётся только записать непосредственно кватернион поворота по формуле (8.1), подставив угол, найденный по (8.2). Упростить вычисления, избавившись от тригонометрических функций, вероятно, не удастся, однако задачи вроде изложенной здесь редко выполняются «в цикле», и особенно гнаться за производительностью не стоит.
Скоро и до современных звёздных датчиков доберёмся.