math - zyx - teorema de rotacion de euler
¿Cómo convertir el vector de dirección a ángulos de Euler? (2)
Veamos si entiendo correctamente. Se trata de la orientación de un cuerpo rígido en el espacio tridimensional, como un avión de aire durante el vuelo. La nariz de ese avión apunta hacia el vector de dirección
D=(XD,YD,ZD) .
Hacia el techo es el vector ascendente
U=(XU,YU,ZU) .
Entonces, el encabezado H
sería el vector de dirección D
proyectado sobre la superficie de la tierra:
H=(XD,YD,0) ,
con un ángulo asociado
angle_H=atan2(YD,XD) .
El tono P sería el ángulo arriba / abajo de la nariz con respecto al horizonte, si el vector de dirección D
está normalizado lo obtienes de
ZD=sin(angle_P)
Resultando en
angle_P=asin(ZD) .
Finalmente, para el ángulo del banco consideramos la dirección de las alas, suponiendo que las alas son perpendiculares al cuerpo. Si el avión vuela directamente hacia D
, las alas apuntan perpendicularmente a D
y son paralelas a la superficie de la tierra:
W0 = ( -YD, XD, 0 )
Este sería un ángulo de inclinación de 0. El vector ascendente esperado sería perpendicular a W0
y perpendicular a D
U0 = W0 × D
con ×
denota el producto cruzado. U
es igual a U0
si el ángulo del banco es cero; de lo contrario, el ángulo entre U
y U0
es el ángulo del banco angle_B
, que se puede calcular a partir de
cos(angle_B) = Dot(U0,U) / abs(U0) / abs(U)
sin(angle_B) = Dot(W0,U) / abs(W0) / abs(U) .
De eso obtienes el ángulo del banco como
angle_B = atan2( Dot(W0,U) / Dot(U0,U) / abs(W0) * abs(U0) ) .
Los factores de normalización se cancelan entre sí si U
y D
están normalizados.
Estoy buscando una forma de convertir el vector de dirección (X, Y, Z) en ángulos de Euler (rumbo, cabeceo, banco). Sé que el vector de dirección por sí solo no es suficiente para obtener el ángulo de inclinación, por lo que también hay otro llamado vector ascendente.
Teniendo el vector de dirección (X, Y, Z) y el vector ascendente (X, Y, Z), ¿cómo convierto eso en ángulos de Euler?
necesitamos tres vectores: X1, Y1, Z1 del sistema de coordenadas local (LCS) expresado en términos del sistema de coordenadas mundiales (WCS). El siguiente código presenta cómo calcular tres ángulos de Euler basados en estos 3 vectores.
#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);
}
}