Есть способ сделать это без использования матриц или векторов, аналогично этой тупой реализации . Мы можем думать о долготе / широте как о двух кватернионных вращениях, составленных вместе.
Давайте работать с правосторонней системой координат Z-up. Назовем долготу φ и широту θ, а точку, представленную двумя, как (φ, θ). Для визуализации красная ось соответствует X, зеленая - Y, а синяя - Z.
Мы хотим найти кватернион, представляющий вращение от (0, 0) красного цвета до ( a , b ), зеленым цветом:
![Sphere with origin and destination points](https://i.stack.imgur.com/wLeU7.png)
Мы можем представить это вращение как комбинацию сначала продольного вращения, затем продольного вращения, вот так:
![Second rotation](https://i.stack.imgur.com/yASbj.png)
Сначала мы повернули на a вдоль оси Z, что преобразует оси X и Y. Затем мы повернулись на b вдоль новой локальной оси Y. Таким образом, мы знаем два набора информации оси / угла для этого вращения.
К счастью, преобразование оси / угла в кватернионы уже известно. Для заданного угла α и вектора оси ω результирующий кватернион равен:
(cos(α/2), ω.x*sin(α/2), ω.y*sin(α/2), ω.z*sin(α/2))
Итак, первое вращение представлено вращением a градусов по мировой (0, 0, 1) оси, что дает нам:
q1 = (cos(a/2), 0, 0, sin(a/2))
Второе вращение представлено поворотом b градусов вдоль преобразованной / локальной (0, 1, 0) оси, давая нам:
q2 = (cos(b/2), 0, sin(b/2), 0)
Мы можем умножить эти два кватерниона, чтобы получить один кватернион, представляющий это сложное вращение от (0, 0) до ( a , b ). Формула для умножения кватернионов немного длинна, но вы можете найти ее здесь . Результат:
q2*q1 = (cos(a/2)cos(b/2), -sin(a/2)sin(b/2), cos(a/2)sin(b/2), sin(a/2)cos(b/2))
Не то, чтобы это много значило, но мы можем подтвердить, что эта формула такая же, как и в ошеломленной реализации, упомянутой ранее.
Дж. Купер упомянул замечательный момент, что в этом случае все еще остается одна степень свободы вдоль оси X. Если θ остается в пределах ± 90 градусов, мы можем представить, что ось Z всегда направлена вверх. Это имеет эффект ограничения вращения оси X и, надеюсь, то, что вы хотите.
Надеюсь, это поможет!
edit: Обратите внимание, что это по сути то же самое, что и работа с двумя углами Эйлера. Таким образом, чтобы отменить это преобразование, вы можете использовать любое преобразование кватерниона в угол Эйлера, при условии, что порядок вращения одинаков.