192 votos

¿Calcular la Matriz de Rotación para alinear el Vector A con el Vector B en 3d?

Tengo un triángulo en el espacio 3d que estoy rastreando en una simulación. Entre los pasos de tiempo tengo la normalidad anterior del triángulo y la normalidad actual del triángulo junto con las posiciones de vértice actual y anterior de los triángulos.

Usando las normales del plano triangular me gustaría determinar una matriz de rotación que alineara las normales de los triángulos, poniendo así los dos triángulos paralelos entre sí. Luego me gustaría usar una matriz de traslación para mapear lo anterior sobre lo actual, sin embargo esta no es mi principal preocupación en este momento.

He encontrado este sitio web http://forums.cgsociety.org/archive/index.php/t-741227.html que dice que debo

  • determinar el producto cruzado de estos dos vectores (para determinar un eje de rotación)
  • determinar el producto del punto (para encontrar el ángulo de rotación)
  • construir el cuaternario (no estoy seguro de lo que esto significa)
  • la matriz de transformación es el cuaternario como un 3 por 3 ( no estoy seguro)

Cualquier ayuda sobre cómo puedo resolver este problema sería apreciada.

2 votos

15 votos

Sé que no es tu principal preocupación en este momento, pero sospecho que se convertirá en una preocupación más adelante: No hay ninguna razón para esperar que después de aplicar una rotación arbitraria alineando las normales los triángulos estén relacionados por una traslación -- todavía tendrías que rotar alrededor de la normal para alinearlos. Dicho de otro modo, no está claro que alinear las normales sea un buen primer paso, ya que luego tienes que realizar dos rotaciones distintas. Puedes obtener el eje de la rotación completa tomando el producto cruzado de los cambios en las diferencias entre dos pares de posiciones de vértices.

2 votos

Ese es un punto muy bueno que ni siquiera había pensado en eso

174voto

Richard Simões Puntos 4981

Supongamos que se quiere encontrar una matriz de rotación $R$ que gira el vector unitario $a$ en el vector unitario $b$ .

Proceda de la siguiente manera:

Dejemos que $v = a \times b$

Dejemos que $s = \|v\|$ (seno del ángulo)

Dejemos que $c = a \cdot b$ (coseno del ángulo)

Entonces la matriz de rotación R viene dada por: $$R = I + [v]_{\times} + [v]_{\times}^2{1-c \over s^2},$$

donde $[v]_{\times}$ es la matriz de producto cruzado sesgado-simétrico de $v$ , $$[v]_{\times} \stackrel{\rm def}{=} \begin{bmatrix} \,\,0 & \!-v_3 & \,\,\,v_2\\ \,\,\,v_3 & 0 & \!-v_1\\ \!-v_2 & \,\,v_1 &\,\,0 \end{bmatrix}.$$

6 votos

Confirmo que esto funciona y da respuestas idénticas a las de mi respuesta .

0 votos

He tratado de implementar esto, sin embargo estoy recibiendo un problema cuando los productos cruzados es 0.

1 votos

El producto cruzado no puede ser 0 porque a y b son vectores unitarios

78voto

Kuba Ober Puntos 274

Utilizando Respuesta de Kjetil respuesta, con proceso91 El comentario de la Sra. G., nos lleva al siguiente procedimiento.

Derivación

Nos dan dos vectores columna unitarios, $A$ y $B$ ( $\|A\|=1$ y $\|B\|=1$ ). El $\|\circ\|$ denota la norma L-2 de $\circ$ .

En primer lugar, hay que tener en cuenta que la rotación de $A$ a $B$ es sólo una rotación 2D en un plano con la normal $A \times B$ . Una rotación 2D por un ángulo $\theta$ viene dada por la siguiente matriz aumentada: $$G=\begin{pmatrix} \cos\theta & -\sin\theta & 0 \\ \sin\theta & \cos\theta & 0 \\ 0 & 0 & 1 \end{pmatrix}.$$

Por supuesto que no queremos computa cualquier función trigonométrica. Dados nuestros vectores unitarios, observamos que $\cos\theta=A\cdot B$ y $\sin\theta=||A\times B||$ . Así, $$G=\begin{pmatrix} A\cdot B & -\|A\times B\| & 0 \\ \|A\times B\| & A\cdot B & 0 \\ 0 & 0 & 1\end{pmatrix}.$$

Esta matriz representa la rotación desde $A$ a $B$ en la base formada por los siguientes vectores columna:

  1. normalizado proyección vectorial de $B$ en $A$ : $$u={(A\cdot B)A \over \|(A\cdot B)A\|}=A$$

  2. normalizado rechazo del vector de $B$ en $A$ : $$v={B-(A\cdot B)A \over \|B- (A\cdot B)A\|}$$

  3. el producto cruzado de $B$ y $A$ : $$w=B \times A$$

Esos vectores son todos ortogonales y normales, y forman una base ortonormal. Este es el detalle que Kjetil había pasado por alto en su responder .

La matriz de cambio de base para esta base es: $$F=\begin{pmatrix}u & v & w \end{pmatrix}^{-1}=\begin{pmatrix} A & {B-(A\cdot B)A \over \|B- (A\cdot B)A\|} & B \times A\end{pmatrix}^{-1}$$

Así, en la base original, la rotación de $A$ a $B$ puede expresarse como una multiplicación por la derecha de un vector por la siguiente matriz: $$U=F^{-1}G F.$$

Se puede demostrar fácilmente que $U A = B$ y que $\|U\|_2=1$ . También, $U$ es el mismo que el $R$ matriz de La respuesta de Rik .

Caso 2D

Para el caso 2D, dado $A=\left(x_1,y_1,0\right)$ y $B=\left(x_2,y_2,0\right)$ la matriz $G$ es la propia matriz de transformación hacia delante, y podemos simplificarla aún más. Observamos que $$\begin{aligned} \cos\theta &= A\cdot B = x_1x_2+y_1y_2 \\ \sin\theta &= \| A\times B\| = x_1y_2-x_2y_1 \end{aligned}$$

Finalmente, $$U\equiv G=\begin{pmatrix} x_1x_2+y_1y_2 & -(x_1y_2-x_2y_1) \\ x_1y_2-x_2y_1 & x_1x_2+y_1y_2 \end{pmatrix}$$ y $$U^{-1}\equiv G^{-1}=\begin{pmatrix} x_1x_2+y_1y_2 & x_1y_2-x_2y_1 \\ -(x_1y_2-x_2y_1) & x_1x_2+y_1y_2 \end{pmatrix}$$

Implementación de Octave/Matlab

La aplicación básica es muy sencilla. Se podría mejorar factorizando las expresiones comunes de dot(A,B) y cross(B,A) . También hay que tener en cuenta que $||A\times B||=||B\times A||$ .

GG = @(A,B) [ dot(A,B) -norm(cross(A,B)) 0;\
              norm(cross(A,B)) dot(A,B)  0;\
              0              0           1];

FFi = @(A,B) [ A (B-dot(A,B)*A)/norm(B-dot(A,B)*A) cross(B,A) ];

UU = @(Fi,G) Fi*G*inv(Fi);

Pruebas:

> a=[1 0 0]'; b=[0 1 0]';
> U = UU(FFi(a,b), GG(a,b));
> norm(U) % is it length-preserving?
ans = 1
> norm(b-U*a) % does it rotate a onto b?
ans = 0
> U
U =

   0  -1   0
   1   0   0
   0   0   1

Ahora con vectores aleatorios:

> vu = @(v) v/norm(v);
> ru = @() vu(rand(3,1));
> a = ru()
a =

   0.043477
   0.036412
   0.998391
> b = ru()
b =

   0.60958
   0.73540
   0.29597
> U = UU(FFi(a,b), GG(a,b));
> norm(U)
ans =  1
> norm(b-U*a)
ans =    2.2888e-16
> U
U =

   0.73680  -0.32931   0.59049
  -0.30976   0.61190   0.72776
  -0.60098  -0.71912   0.34884

Aplicación de la respuesta de Rik

Es un poco más eficiente computacionalmente utilizar Rik's respuesta. Esta es también una implementación de Octave/MatLab.

ssc = @(v) [0 -v(3) v(2); v(3) 0 -v(1); -v(2) v(1) 0]
RU = @(A,B) eye(3) + ssc(cross(A,B)) + \
     ssc(cross(A,B))^2*(1-dot(A,B))/(norm(cross(A,B))^2)

Los resultados producidos son los mismos que los anteriores, con errores numéricos ligeramente menores ya que se realizan menos operaciones.

1 votos

Notación de Matlab para la implementación de Rik: function R=fcn_RotationFromTwoVectors(A, B) v = cross(A,B); ssc = [0 -v(3) v(2); v(3) 0 -v(1); -v(2) v(1) 0]; R = eye(3) + ssc + ssc^2*(1-dot(A,B))/(norm(v))^2;

0 votos

@phyatt ¿La sintaxis lambda no funciona también en Matlab?

1 votos

He usado lamdas en otros lenguajes, y no lo he visto en uso en los proyectos de Matlab... y claro, está ahí. mathworks.com/help/matlab/matlab_prog/anonymous-functions.html Gracias @KuberOber.

9voto

mikemurf22 Puntos 817

En la parte superior de mi cabeza (hacer la comprobación usted mismo) Que los vectores dados en $R^3$ sea $A$ y $B$ para simplificar se supone que tienen norma 1, y se supone que no son idénticas. Definir $C$ como el producto cruzado de $A$ y $B$ . Queremos una matriz ortogonal $U$ tal que $UA=B$ y $UC=C$ . Primero cambiar las bases, a la nueva base $(U_1,u_2,u_3)=(A,B,C)$ . En esta nueva base la matriz que hace el trabajo es simplemente $G=\left(\begin{smallmatrix} 0&1&0\\1&0&0\\0&0&1\end{smallmatrix}\right)$ . Entonces necesitamos la matriz de desplazamiento de la base, a la nueva base. Escriba las coordenadas de los vectores en la base antigua simplemente como $A=(a_1,a_2,a_3), B=(b_1,b_2,b_3), C=(c_1,c_2,c_3)$ . Entonces la matriz de desplazamiento de base puede verse como $\left( \begin{smallmatrix} a_1&b_1&c_1\\a_2&b_2&c_2\\a_3&b_3&c_3 \end{smallmatrix}\right)^{-1}$ . El resultado es ahora simplemente $U=F^{-1} G F$ que es una matriz ortogonal que gira $A$ en $B$ .

1 votos

En realidad, creo que puede haber más problemas - su matriz $U$ sólo se garantiza que sea ortogonal si $F$ es, que sólo es el caso si $A$ y $B$ son ortogonales. En otros casos, los ángulos de varios otros vectores a los que $U$ se aplica puede ser estirada o comprimida.

0 votos

Sin embargo, tu proceso de reflexión es bueno: ¡no te rindas todavía! Creo que hay una solución de esta manera si usted considera diferentes vectores base originales que todavía tienen una forma fácilmente representada de $A$ y $B$ . Por ejemplo, podría elegir la proyección de $A$ en $B$ el rechazo de $A$ en $B$ y $A \times B$ .

5 votos

Sólo para que la gente no se descarrile: esta respuesta no funciona tal cual, hay que tener en cuenta los comentarios de process91. +1 ya que proporcionó una valiosa inspiración.

5voto

glennr Puntos 121

Utilice Fórmula de rotación de Rodrigues (Véase el apartado "Conversión a matriz de rotación"). $\cos\theta$ es el producto punto de los vectores iniciales normalizados y $\sin\theta$ se puede determinar a partir de $\sin^2\theta + \cos^2\theta =1$

0 votos

No creo que $\sin \theta$ puede determinarse de esa manera. Existe una ambigüedad de signos. (Si no fuera así, obtendríamos la misma matriz de rotación para pasar de $a$ a $b$ y viceversa).

0 votos

¿Podría ser que la fórmula en Wikipedia en es.wikipedia.org/wiki/ ¿falta un cos antes de la matriz de identidad? No capto la explicación de por qué se ha eliminado.

4voto

Vilid Puntos 300

El cuaternión es un número complejo de 4 dimensiones: http://en.wikipedia.org/wiki/Quaternion utilizado para describir las rotaciones en el espacio. Un cuaternión (como un número complejo) tiene una representación polar que implica el exponencial de los argumentos (rotaciones), y un multiplicador magnético. La construcción del cuaternión viene del producto cruzado (el producto de los componentes complejos), que te dará el argumento en esas 3 dimensiones, entonces obtendrás un número de eso en la forma A+Bi+Cj+Dk, y lo escribirás en la forma de matriz descrita en el artículo allí.

Una manera más fácil sería simplemente averiguar cuáles son tus vectores originales en el espacio 4, y tomar las operaciones inversas apropiadas para obtener tu cuaternión resultante (sin pasar por los pasos del producto punto/cruz) pero eso requiere una buena base en álgebra hipercompleja.

1 votos

Para que quede claro: por el artículo, el producto punto será su parte escalar, y el producto cruz la parte vectorial, así que con producto punto: x y producto escalar iy + jz + ka el cuaternión q sería q = x +iy +jz +ka.

0 votos

No exactamente. Si el producto punto es a, y el producto cruz es (x, y, z), sería cos(a/2) + (x * sin(a/2))i + (y * sin(a/2))j + ( z * sin(a/2))k. Los cuaterniones de rotación son unitarios.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X