Как преобразовать вектор направления в углы Эйлера?
Я ищу способ преобразования вектора направления (X,Y, Z) в углы Эйлера (заголовок, шаг, банк). Я знаю, что вектор направления сам по себе недостаточно, чтобы получить угол крена, поэтому есть еще один так называемый вектор.
имея вектор направления (X,Y,Z) и вектор вверх (X,Y, Z), как преобразовать это в углы Эйлера?
2 ответов
посмотрим, правильно ли я понял. Это об ориентации твердого тела в трехмерном пространстве, как самолет во время полета. Нос этого самолета указывает на направление вектора
D=(XD,YD,ZD) .
на крыше вектор
U=(XU,YU,ZU) .
затем заголовок H
будет вектор направления D
проецируется на поверхность Земли:
H=(XD,YD,0) ,
С связанный угол
angle_H=atan2(YD,XD) .
поле P будет углом вверх / вниз носа по отношению к горизонту, если вектор направления D
нормализовано вы получаете его от
ZD=sin(angle_P)
в результате
angle_P=asin(ZD) .
наконец, для угла крена мы рассматриваем направление крыльев, предполагая, что крылья перпендикулярны телу. Если самолет летит прямо на D
крылья точку перпендикулярно D
и параллельно поверхности Земли:
W0 = ( -YD, XD, 0 )
это будет угол крена 0. Ожидаемый вектор будет перпендикулярен W0
перпендикулярно D
U0 = W0 × D
С ×
обозначив произведение. U
равна U0
если угол банка равен нулю, в противном случае угол между U
и U0
угол банка angle_B
, который может быть рассчитан с
cos(angle_B) = Dot(U0,U) / abs(U0) / abs(U)
sin(angle_B) = Dot(W0,U) / abs(W0) / abs(U) .
здесь ' abs ' вычисляет длину вектора. Из этого вы получаете угол банка как
angle_B = atan2( Dot(W0,U) / abs(W0), Dot(U0,U) / abs(U0) ) .
коэффициенты нормализации отменяют друг друга, если U
и D
нормализуются.
нам нужны три вектора: X1, Y1, Z1 локальной системы координат (LCS), выраженной в терминах мировой системы координат (WCS). В приведенном ниже коде показано, как вычислить три угла Эйлера на основе этих 3 векторов.
#include <math.h>
#include <float.h>
#define PI 3.141592653589793
/**
* @param X1x
* @param X1y
* @param X1z X1 vector coordinates
* @param Y1x
* @param Y1y
* @param Y1z Y1 vector coordinates
* @param Z1x
* @param Z1y
* @param Z1z Z1 vector coordinates
* @param pre precession rotation
* @param nut nutation rotation
* @param rot intrinsic rotation
*/
void lcs2Euler(
double X1x, double X1y, double X1z,
double Y1x, double Y1y, double Y1z,
double Z1x, double Z1y, double Z1z,
double *pre, double *nut, double *rot) {
double Z1xy = sqrt(Z1x * Z1x + Z1y * Z1y);
if (Z1xy > DBL_EPSILON) {
*pre = atan2(Y1x * Z1y - Y1y*Z1x, X1x * Z1y - X1y * Z1x);
*nut = atan2(Z1xy, Z1z);
*rot = -atan2(-Z1x, Z1y);
}
else {
*pre = 0.;
*nut = (Z1z > 0.) ? 0. : PI;
*rot = -atan2(X1y, X1x);
}
}