Примечание: вместо «yaw, pitch, roll» я буду использовать условные обозначения «heading, pitch, bank», как определено в 3D Math Primer для разработки графики и игр от Fletcher Dunn .
Во-первых, обратите внимание, что в 2D-системе координат вам нужен только один угол + величина, чтобы "указать" на любую точку в 2D.
Аналогично, в 3D-системе координат вы нужны только два угла + величина, чтобы "указать" на любую точку в 3D. Последний угол («банк» или «крен») не влияет на местоположение точки в 3D. Вместо этого он «раскручивает» стрелку, которая будет указывать на него. Если объект симметричен на 360 градусов, вращение не будет влиять на объект вообще. Если объект не является симметричным (например, самолет), это повлияет на объект (например, наклон одного крыла к земле, а другого к небу).
Таким образом, на самом деле возникает первоначальный вопрос: «Как мне найтиугол направления, угол наклона и величина, чтобы «указать» на любую точку в трехмерном пространстве? »
Вы можете легко понять это, используя функции тригонометрии. Представьте, что у нас есть точка (1,2,3)
, и мы пытаемся вычислить курс, шаг, величину.
Для следующего примера, давайте использовать эту диаграмму, где левая ось - X, вверх - Y, исправа - Z. Точка (1,2,3)
, затем представлена синей сферой.
1. Найти величину
Сначала давайте найдем самое простое значение - величину. К счастью для нас, легко определить величину (длину) между любыми двумя точками вне зависимости от того, в скольких измерениях мы находимся, просто используя теорему Пифагора . Поскольку мы находимся в 3D и рассчитываем расстояние от начала координат до нашей точки, наша формула расстояния принимает вид:
magnitude = sqrt(x*x + y*y + z*z)
Включая наши действительные значения:
magnitude = sqrt(1*1 + 2*2 + 3*3)
= 3.7416573868
Таким образом, наша величина (или длина) составляет ~ 3.741
.
2. Найдите заголовок
Далее, чтобы найти заголовок, обратите внимание, что мы просто заботимся о вращении вокруг плоскости XZ, а нас вообще не волнует ось Y. Если бы мы «сгладили» трехмерное пространство в 2D, становится тривиальным, чтобы найти заголовок .
. Мы можем нарисовать треугольник, который образует угол 90 градусов с осью X (красный треугольник), а затем рассчитать этот угол. Напомним из тригонометрии tan(angle) = opposite / adjacent
и, решив для angle
, получим angle = arctan(opposite / adjacent)
.
. В этом случае «смежный» - это известная величина (redAdjacent = x = 1
), а «противоположный» тоже известен (redOpposite = z = 3
). Вместо того чтобы использовать arctan для решения уравнения, мы хотим использовать atan2 , поскольку он будет обрабатывать все различные случаи x и y для нас.
Итак, у нас есть:
heading = atan2(redOpposite, redAdjacent)
Включение наших фактических значений:
heading = atan2(3, 1)
= 1.249045772398
, поэтому наш заголовок равен 1.249
рад, или ~ 72°
.
3. Найти поле
Наконец нам нужно найти поле. Аналогично тому, что мы сделали с заголовком, мы можем сгладить трехмерное пространство в 2D вдоль плоскости, содержащей эти три точки: (A) начало координат (0,0,0)
, (B) наша точка (1,2,3)
и (C) нашиточка, как это будет проецироваться на плоскость XZ (1,0,3)
(например, путем установки 0 для значения Y).
Если мы нарисуем треугольник между всеми 3 из этих точек, вы заметите, что они образуют правую-треугольник снова (зеленый треугольник). Мы можем просто вычислить угол, используя arctan2
снова.
Мы уже вычислили зеленую гипотенузу на шаге 1 (то есть величину нашего вектора):
greenHypotenuse = sqrt(x*x + y*y + z*z)
= 3.7416573868
Мы также знаем обратноезеленого треугольника совпадает со значением у:
greenOpposite = y
= 2
Используя теорему Пифагора, мы можем найти длину соседнего угла:
greenOpposite^2 + greenAdjacent^2 = greenHypotenuse^2
y*y + greenAdjacent^2 = x*x + y*y + z*z
greenAdjacent^2 = x*x + z*z
greenAdjacent = sqrt(x*x + z*z)
Обратите внимание, что по-другомуЧтобы вычислить смежную длину зеленого треугольника, нужно заметить, что redHypotenuse == greenAdjacent
, и мы можем найти redHypotenuse
, используя:
redHypotenuse^2 = redAdjacent^2 + redOpposite^2
= x*x + z*z
redHypotenuse = sqrt(x*x + z*z)
Подставляя фактические значения, мы получим:
greenAdjacent = sqrt(1*1 + 3*3)
= 3.1622776602
Итак, теперь, когда мы знаем смежные и противоположные длины зеленого треугольника, мы можем снова использовать arctan2
:
pitch = atan2(greenOpposite, greenAdjacent)
= atan2(2, 3.1622776602)
= 0.563942641356
Таким образом, наша высота равна 0.5634
радиан, или примерно 32°
.
Заключение
Если вы хотите нарисовать линию от начала координат с длиной3.741
, заголовок 1.249
рад и шаг 0.564
рад, он будет расширяться от (0,0,0)
до (1,2,3)
.