Как преобразовать углы Эйлера в направленный вектор?

У меня есть углы наклона, рулона и рыскания. Как бы преобразовать их в вектор направленности?

Было бы особенно здорово, если бы вы могли показать мне кватернион и / или матричное представление этого!

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

Если мы определяем pitch = 0 как горизонтальный (z = 0) и yaw как против часовой стрелки от оси x, тогда вектор направления будет

 x = cos (yaw) * cos (pitch)
 y = sin (yaw) * cos (pitch)
 z = sin (шаг)

Обратите внимание, что я не использовал roll; это вектор единицы направления, он не указывает отношения. Достаточно легко написать матрицу вращения, которая будет переносить вещи в кадр летающего объекта (если вы хотите знать, скажем, где указывает левый крыло), но это действительно хорошая идея, чтобы сначала определить соглашения. Не могли бы вы рассказать нам больше о проблеме?

EDIT: (Я хотел бы вернуться к этому вопросу в течение двух с половиной лет.)

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

Первый бросок:

| 1 0 0 | | 0 cos(roll) -sin(roll) | | 0 sin(roll) cos(roll) | 

затем шаг:

 | cos(pitch) 0 -sin(pitch) | | 0 1 0 | | sin(pitch) 0 cos(pitch) | 

затем рыскание:

 | cos(yaw) -sin(yaw) 0 | | sin(yaw) cos(yaw) 0 | | 0 0 1 | 

Объедините их, и общая matrix вращения:

 | cos(yaw)cos(pitch) -cos(yaw)sin(pitch)sin(roll)-sin(yaw)cos(roll) -cos(yaw)sin(pitch)cos(roll)+sin(yaw)sin(roll)| | sin(yaw)cos(pitch) -sin(yaw)sin(pitch)sin(roll)+cos(yaw)cos(roll) -sin(yaw)sin(pitch)cos(roll)-cos(yaw)sin(roll)| | sin(pitch) cos(pitch)sin(roll) cos(pitch)sin(roll)| 

Итак, для единичного вектора, начинающегося с оси x, конечные координаты будут:

 x = cos(yaw)cos(pitch) y = sin(yaw)cos(pitch) z = sin(pitch) 

А для единичного вектора, который начинается с оси y (левый крыло), конечные координаты будут:

 x = -cos(yaw)sin(pitch)sin(roll)-sin(yaw)cos(roll) y = -sin(yaw)sin(pitch)sin(roll)+cos(yaw)cos(roll) z = cos(pitch)sin(roll) 

Существует шесть различных способов преобразования трех углов Эйлера в матрицу в зависимости от Приказа, который они применяют:

 typedef float Matrix[3][3]; struct EulerAngle { float X,Y,Z; }; // Euler Order enum. enum EEulerOrder { ORDER_XYZ, ORDER_YZX, ORDER_ZXY, ORDER_ZYX, ORDER_YXZ, ORDER_XZY }; Matrix EulerAnglesToMatrix(const EulerAngle &inEulerAngle,EEulerOrder EulerOrder) { // Convert Euler Angles passed in a vector of Radians // into a rotation matrix. The individual Euler Angles are // processed in the order requested. Matrix Mx; const FLOAT Sx = sinf(inEulerAngle.X); const FLOAT Sy = sinf(inEulerAngle.Y); const FLOAT Sz = sinf(inEulerAngle.Z); const FLOAT Cx = cosf(inEulerAngle.X); const FLOAT Cy = cosf(inEulerAngle.Y); const FLOAT Cz = cosf(inEulerAngle.Z); switch(EulerOrder) { case ORDER_XYZ: Mx.M[0][0]=Cy*Cz; Mx.M[0][1]=-Cy*Sz; Mx.M[0][2]=Sy; Mx.M[1][0]=Cz*Sx*Sy+Cx*Sz; Mx.M[1][1]=Cx*Cz-Sx*Sy*Sz; Mx.M[1][2]=-Cy*Sx; Mx.M[2][0]=-Cx*Cz*Sy+Sx*Sz; Mx.M[2][1]=Cz*Sx+Cx*Sy*Sz; Mx.M[2][2]=Cx*Cy; break; case ORDER_YZX: Mx.M[0][0]=Cy*Cz; Mx.M[0][1]=Sx*Sy-Cx*Cy*Sz; Mx.M[0][2]=Cx*Sy+Cy*Sx*Sz; Mx.M[1][0]=Sz; Mx.M[1][1]=Cx*Cz; Mx.M[1][2]=-Cz*Sx; Mx.M[2][0]=-Cz*Sy; Mx.M[2][1]=Cy*Sx+Cx*Sy*Sz; Mx.M[2][2]=Cx*Cy-Sx*Sy*Sz; break; case ORDER_ZXY: Mx.M[0][0]=Cy*Cz-Sx*Sy*Sz; Mx.M[0][1]=-Cx*Sz; Mx.M[0][2]=Cz*Sy+Cy*Sx*Sz; Mx.M[1][0]=Cz*Sx*Sy+Cy*Sz; Mx.M[1][1]=Cx*Cz; Mx.M[1][2]=-Cy*Cz*Sx+Sy*Sz; Mx.M[2][0]=-Cx*Sy; Mx.M[2][1]=Sx; Mx.M[2][2]=Cx*Cy; break; case ORDER_ZYX: Mx.M[0][0]=Cy*Cz; Mx.M[0][1]=Cz*Sx*Sy-Cx*Sz; Mx.M[0][2]=Cx*Cz*Sy+Sx*Sz; Mx.M[1][0]=Cy*Sz; Mx.M[1][1]=Cx*Cz+Sx*Sy*Sz; Mx.M[1][2]=-Cz*Sx+Cx*Sy*Sz; Mx.M[2][0]=-Sy; Mx.M[2][1]=Cy*Sx; Mx.M[2][2]=Cx*Cy; break; case ORDER_YXZ: Mx.M[0][0]=Cy*Cz+Sx*Sy*Sz; Mx.M[0][1]=Cz*Sx*Sy-Cy*Sz; Mx.M[0][2]=Cx*Sy; Mx.M[1][0]=Cx*Sz; Mx.M[1][1]=Cx*Cz; Mx.M[1][2]=-Sx; Mx.M[2][0]=-Cz*Sy+Cy*Sx*Sz; Mx.M[2][1]=Cy*Cz*Sx+Sy*Sz; Mx.M[2][2]=Cx*Cy; break; case ORDER_XZY: Mx.M[0][0]=Cy*Cz; Mx.M[0][1]=-Sz; Mx.M[0][2]=Cz*Sy; Mx.M[1][0]=Sx*Sy+Cx*Cy*Sz; Mx.M[1][1]=Cx*Cz; Mx.M[1][2]=-Cy*Sx+Cx*Sy*Sz; Mx.M[2][0]=-Cx*Sy+Cy*Sx*Sz; Mx.M[2][1]=Cz*Sx; Mx.M[2][2]=Cx*Cy+Sx*Sy*Sz; break; } return(Mx); } 

FWIW, некоторые процессоры могут одновременно вычислить Sin & Cos (например, fsincos на x86). Если вы это сделаете, вы можете сделать это немного быстрее с тремя вызовами вместо 6, чтобы вычислить начальные значения sin & cos.

Обновление: Есть фактически 12 способов, зависящих, если вы хотите правша или левые результаты – вы можете изменить «ручность», отрицая углы.

Бета спасла мой день. Тем не менее, я использую немного другую систему координат, и мое определение шага вверх \ вниз (кивая головой в согласии), где положительный шаг приводит к отрицательному y-компоненту. Мой опорный вектор – это стиль OpenGl (вниз по оси -z), поэтому с yaw = 0, pitch = 0 результирующий единичный вектор должен быть равен (0, 0, -1). Если кто-то сталкивается с этим сообщением и испытывает трудности с переводом формул Беты на эту конкретную систему, я использую следующие уравнения:

 vDir->X = sin(yaw); vDir->Y = -(sin(pitch)*cos(yaw)); vDir->Z = -(cos(pitch)*cos(yaw)); 

Обратите внимание на изменение знака и подмену тангажа <->. Надеюсь, это немного сэкономит.

Вы должны четко понимать свои определения здесь – в частности, какой вектор вы хотите? Если это направление, на которое указывает самолет, рулон даже не влияет на него, и вы используете сферические координаты (возможно, с перестановкой осей / углов).

Если, с другой стороны, вы хотите взять данный вектор и преобразовать его по этим углам, вы ищете матрицу вращения. В статье wiki о matrixх вращения содержится формула для поворота поворотного вала, основанная на matrixх вращения xyz. Я не собираюсь вводить его здесь, учитывая связанные с ним греческие буквы и матрицы.

Если кто-то наткнется на поиск в FreeCAD.

 import FreeCAD, FreeCADGui from FreeCAD import Vector from math import sin, cos, pi cr = FreeCADGui.ActiveDocument.ActiveView.getCameraOrientation().toEuler() crx = cr[2] # Roll cry = cr[1] # Pitch crz = cr[0] # Yaw crx = crx * pi / 180.0 cry = cry * pi / 180.0 crz = crz * pi / 180.0 x = sin(crz) y = -(sin(crx) * cos(crz)) z = cos(crx) * cos(cry) view = Vector(x, y, z) 
  • Как проверить случайность (пример - перетасовка)
  • Как определить, находится ли точка в правой или левой части строки
  • OCR и сходство символов
  • Что такое нерекурсивное решение для последовательности, подобной Фибоначчи, в Java?
  • Головоломка: найдите самый большой прямоугольник (проблема с максимальным прямоугольником)
  • Оценка строки "3 * (4 + 2)" yield int 18
  • Операции с плавающей запятой в C-ассоциативном?
  • Простой алгоритм пересечения многоугольников
  • Как вы находите точку на заданном перпендикулярном расстоянии от линии?
  • Представление целых чисел в двухместных
  • Как определить, соответствует ли список точек полигона по часовой стрелке?
  • Interesting Posts

    Как получить доступ к защищенному Nexus с помощью sbt?

    Строковые литералы: указатель против массива символов

    Невозможно преобразовать массив типа значения в объект params

    jQuery.ajax не работает, когда URL-адрес с другого сервера

    Как решить проблему «Bootmgr is missing» на компьютере под управлением Windows 7?

    Синтаксис для однострочного бесконечного цикла Bash

    Каков наилучший способ получить минимальное или максимальное значение из массива чисел?

    Понимание примера преобразования lvalue-to-rvalue

    Как я могу запретить Visual Studio 2013 закрывать приложение IIS Express при завершении отладки?

    Сетевой адаптер в Hyper-V сбрасывается на DockerNAT

    Что такое Apache Camel?

    Понимание разницы между f () и f (void) в C и C ++ раз и навсегда

    FileZilla в Mac OS X не может открыть .ssh-каталог, чтобы получить мой ключевой файл

    Repeater, ListView, DataList, DataGrid, GridView … Что выбрать?

    Gnome3 предопределяет виртуальные рабочие столы

    Давайте будем гением компьютера.