Porque soy un usuario nuevo, no puedo publicar imágenes, hipervínculos o links, hay una versión completa con imágenes aquí:
El problema que tengo, es que necesito para convertir de $XYZ$ eje fijo de rotación, a Euler rotaciones $Z$,, a continuación,$X'$,, a continuación,$Z''$.
Aquí los matricies:
$$X = \left(\begin{matrix} 1 & 0 & 0 \\ 0 & \cos(\theta) & -\sin(\theta) \\ 0 & \sin(\theta) & \cos(\theta)\end{matrix}\right)$$
$$Y = \left(\begin{matrix} \cos(\phi) & 0 & \sin(\phi) \\ 0 & 1 & 0 \\ -\sin(\phi) & 0 & \cos(\phi)\end{matrix}\right)$$
$$Z = \left(\begin{matrix} \cos(\psi) & -\sin(\psi) & 0 \\ \sin(\psi) & \cos(\psi) & 0 \\ 0 & 0 & 1\end{matrix}\right)$$
Combined, as $R_z(\psi) R_y(\phi) R_x(\theta) = R_{xyz}(\theta,\phi\psi)$; they give:
$R_{xyz}$: i.imgur.com/8UQM6.jpg
And the Rotation matrix for the Specific convention of Euler angles I want; is this:
Euler:
So my initial plan, was to compare matrix elements, and extract the angles I wanted that way; I came up with this (actual current code at the end):
But this doesn't work under several circumstances. The most obvious being when $\cos(\theta)\cos(\phi) = 1$; since then $\cos(\beta) = 1$, and so $\sin(\beta) = 0$. Where $\sin(\beta)$ is s2
in the code. This happens only when $\cos(\theta)$ and $\cos(\phi) = \pm 1$.
So right away I can just rule out the possible situations;
When $\theta$ or $\phi = 0, 180, 360, 540, \ldots$, then $\cos(\theta)$, and $\cos(\phi)$ are $\pm 1$;
so I only need to do it differently for these cases;
And I ended up with this code:
public static double[] ZXZtoEuler(double θ, double φ, double ψ){
θ *= Math.PI/180.0;
φ *= Math.PI/180.0;
ψ *= Math.PI/180.0;
double α = -1;
double β = -1;
double γ = -1;
double c2 = Math.cos(θ) * Math.cos(φ);
β = Math.acos(r(c2));
if(eq(c2,1) || eq(c2,-1)){
if(eq(Math.cos(θ),1)){
if(eq(Math.cos(φ),1)){
α = 0.0;
γ = ψ;
}else if(eq(Math.cos(φ),-1)){
α = 0.0;
γ = Math.PI - ψ;
}
}else if(eq(Math.cos(θ),-1)){
if(eq(Math.cos(φ),1)){
α = 0.0;
γ = -ψ;
}else if(eq(Math.cos(φ),-1)){
α = 0.0;
γ = ψ + Math.PI;
}
}
}else{
//original way
double s2 = Math.sin(β);
double c3 = ( Math.sin(θ) * Math.cos(φ) )/ s2;
double s1 = ( Math.sin(θ) * Math.sin(ψ) + Math.cos(θ) * Math.sin(φ) * Math.cos(ψ) )/s2;
γ = Math.acos(r(c3));
α = Math.asin(r(s1));
}
α *= 180/Math.PI;
β *= 180/Math.PI;
γ *= 180/Math.PI;
return new double[] {r(α), r(β), r(γ)};
}
Where r
and eq
are just two simple functions;
public static double r(double a){
double prec = 1000000000.0;
return Math.round(a*prec)/prec;
}
static double thresh = 1E-4;
public static boolean eq(double a, double b){
return (Math.abs(a-b) < thresh);
}
eq
is just to compare the numbers for tests, and r
is to prevent floating point errors pushing numbers outside the range of Math.acos
/ Math.asin
and giving me NaN
results;
(i.e. every now and then I'd end up with Math.acos(1.000000000000000004)
or something.)
Which takes into account the 4 cases of having rotations around $x$ and $s$ which leave c2==1
.
But now is where the problem occurs;
Everything I have done above, makes sense to me, but it does not give the correct angles;
Here is some output, in each pair, the first are the $\theta, \phi \psi$ angles, and the second of each pair is the corresponding $\alpha, \beta \gamma$ líneas. Ignorando los errores de redondeo, se parece conseguir algunos de los ángulos de aproximadamente
[0.0, 0.0, 0.0] - correcto! [0.0, 0.0, 0.0]
[0.0, 0.0, 45.0] - correcto! [0.0, 0.0, 45.0]
[0.0, 0.0, 90.0] - correcto! [0.0, 0.0, 90.0]
[0.0, 0.0, 135.0] - correcto! [0.0, 0.0, 135.0]
[0.0, 0.0, 180.0] - correcto [0.0, 0.0, 180.0]
[0.0, 0.0, 225.0] - correcto [0.0, 0.0, 225.0]
[0.0, 0.0, 270.0] - correcto [0.0, 0.0, 270.0]
[0.0, 0.0, 315.0] - correcto [0.0, 0.0, 315.0]
[0.0, 45.0, 0.0] - incorrecto: debe ser [90, 45, -90] [90.0, 44.999982, 90.0]
[0.0, 45.0, 45.0] [45.000018, 44.999982, 90.0]
[0.0, 45.0, 90.0] [0.0, 44.999982, 90.0]
[0.0, 45.0, 135.0] [-45.000018, 44.999982, 90.0]
[0.0, 45.0, 180.0] [-90.0, 44.999982, 90.0]
[0.0, 45.0, 225.0] [-45.000018, 44.999982, 90.0]
[0.0, 45.0, 270.0] [0.0, 44.999982, 90.0]
[0.0, 45.0, 315.0] [45.000018, 44.999982, 90.0]
[0.0, 90.0, 0.0] [90.0, 90.0, 90.0]
[0.0, 90.0, 45.0] [45.000018, 90.0, 90.0]
[0.0, 90.0, 90.0] [0.0, 90.0, 90.0]
[0.0, 90.0, 135.0] [-45.000018, 90.0, 90.0]
[0.0, 90.0, 180.0] [-90.0, 90.0, 90.0]
[0.0, 90.0, 225.0] [-45.000018, 90.0, 90.0]
¿Alguien puede pensar en una solución?
EDIT: no sé si esto ayuda, pero hay algunas otras maneras de mirar en estas rotaciones:
Una forma de rotar alrededor de un eje arbitrario, es reorientar que el eje de la Z Eje y, a continuación, hacer la inversa de la reorientación; se puede aplicar una y otra, para obtener las rotaciones de Euler en términos de la original eje fijo rotaciones;
$$R_{Z^{\prime\prime} X^{\prime} Z}(\alpha,\beta,\gamma) = R_{Z^{\prime\prime}}(\gamma)R_{X^{\prime}}(\beta)R_Z(\alpha)$$
$$R_{X^{\prime}}(\beta) = R_Z(\alpha)R_Y(\frac{\pi}{2})R_Z(\beta)R_Y(-\frac{\pi}{2})R_Z(-\alpha)$$
so
$$R_{X^{\prime}}(\beta)R_Z(\alpha) = R_Z(\alpha)R_Y(\frac{\pi}{2})R_Z(\beta)R_Y(-\frac{\pi}{2})$$
$$R_{Z^{\prime\prime}} = R_Z(\alpha)R_Y(\frac{\pi}{2})R_Z(\beta)R_Y(-\frac{\pi}{2})R_Z(\gamma)R_Y(\frac{\pi}{2})R_Z(-\beta)R_Y(-\frac{\pi}{2})R_Z(-\alpha)$$
And so the whole thing;
$$R_{Z^{\prime\prime}}(\gamma)R_{X^{\prime}}(\beta)R_Z(\alpha) = R_Z(\alpha)R_Y(\frac{\pi}{2})R_Z(\beta)R_Y(-\frac{\pi}{2})R_Z(\gamma)R_Y(\frac{\pi}{2})R_Z(-\beta)R_Y(-\frac{\pi}{2})R_Z(-\alpha)R_Z(\alpha)R_Y(\frac{\pi}{2})R_Z(\beta)R_Y(-\frac{\pi}{2})$$
Which cancels down;
$$R_{Z^{\prime\prime}}(\gamma)R_{X^{\prime}}(\beta)R_Z(\alpha) = R_Z(\alpha)R_Y(\frac{\pi}{2})R_Z(\beta)R_Y(-\frac{\pi}{2})R_Z(\gamma)R_Y(\frac{\pi}{2})R_Z(-\beta)\mathbf{R_Y(-\frac{\pi}{2})R_Y(\frac{\pi}{2})}R_Z(\beta)R_Y(-\frac{\pi}{2})$$
$$R_{Z^{\prime\prime}}(\gamma)R_{X^{\prime}}(\beta)R_Z(\alpha) = R_Z(\alpha)R_Y(\frac{\pi}{2})R_Z(\beta)R_Y(-\frac{\pi}{2})R_Z(\gamma)R_Y(\frac{\pi}{2})\mathbf{R_Z(-\beta)R_Z(\beta)}R_Y(-\frac{\pi}{2})$$
$$R_{Z^{\prime\prime}}(\gamma)R_{X^{\prime}}(\beta)R_Z(\alpha) = R_Z(\alpha)R_Y(\frac{\pi}{2})R_Z(\beta)R_Y(-\frac{\pi}{2})R_Z(\gamma)\mathbf{R_Y(\frac{\pi}{2})R_Y(-\frac{\pi}{2})}$$
$$R_{Z^{\prime\prime}}(\gamma)R_{X^{\prime}}(\beta)R_Z(\alpha) = R_Z(\alpha)R_Y(\frac{\pi}{2})R_Z(\beta)R_Y(-\frac{\pi}{2})R_Z(\gamma)$$
Y tenga en cuenta que $$R_Y(\frac{\pi}{2})R_Z(\beta)R_Y(-\frac{\pi}{2}) = R_X(\beta)$$
así tenemos $$R_{Z^{\prime\prime}}(\gamma)R_{X^{\prime}}(\beta)R_Z(\alpha) = R_Z(\alpha)R_X(\beta)R_Z(\gamma)$$
Ahora no estoy seguro de lo mucho que esto podría ayudar... pero es algo, supongo...