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:
-
normalizado proyección vectorial de $B$ en $A$ : $$u={(A\cdot B)A \over \|(A\cdot B)A\|}=A$$
-
normalizado rechazo del vector de $B$ en $A$ : $$v={B-(A\cdot B)A \over \|B- (A\cdot B)A\|}$$
-
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.
2 votos
Esto puede ser útil: gamedev.stackexchange.com/questions/20097/
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
0 votos
@joriki No estoy seguro de lo que quieres decir con "cambios en las diferencias" ¿te refieres a cruzar los vectores (A' - A) con (B'- B) donde A, B son las posiciones de los vértices del triángulo anterior y los primos son las posiciones de los vértices correspondientes en el triángulo actual, (me cuesta imaginar por qué este producto cruzado daría un eje que permitiría la rotación completa)
3 votos
@user1084113: No, eso sería el producto cruzado de los cambios en las posiciones de dos vértices; me refería al producto cruzado de los cambios en las diferencias entre dos pares de posiciones de vértices, que sería $((A-B)-(A'-B'))\times((B-C)\times(B'-C'))$ . Esto te da el eje de rotación (excepto si está en el plano del triángulo) porque la traslación cae debido a las diferencias, así que esto es puramente el cambio en dos vectores diferentes debido a la rotación. La traslación no desaparecería en tu versión.
0 votos
@joriki Lo siento si esto puede parecer una tontería. Dado que el vector resultante del producto cruzado es el eje de rotación, ¿por qué punto pasa este eje de rotación? Es por el origen o por uno de los puntos del triángulo, estoy tratando de imaginarlo físicamente.
5 votos
@user1084113: No hay una respuesta canónica a esa pregunta. Una isometría que preserva la orientación de $\mathbb R^3$ puede escribirse como una composición de una rotación y una traslación (en cualquier orden), pero esta descomposición no es única: puede desplazar el eje de rotación y compensarlo realizando una traslación diferente. Por lo tanto, sólo puede determinar la dirección del eje a partir de los datos, no su posición. Puede elegir la posición de forma arbitraria, por ejemplo, a través del origen, y elegir la traslación en consecuencia.
0 votos
¿Responde esto a su pregunta? $n$ -rotación a lo largo de un plano arbitrario en 2D
0 votos
@joriki debería ser
((B-C)-(B'-C'))
? También, ¿qué hacemos una vez que tenemos el eje de rotación?