# Calculate Rotation Matrix to align Vector A to Vector B in 3d?

I have one triangle in 3d space that I am tracking in a simulation. Between time steps I have the the previous normal of the triangle and the current normal of the triangle along with both the current and previous 3d vertex positions of the triangles.

Using the normals of the triangular plane I would like to determine a rotation matrix that would align the normals of the triangles thereby setting the two triangles parallel to each other. I would then like to use a translation matrix to map the previous onto the current, however this is not my main concern right now.

I have found this website http://forums.cgsociety.org/archive/index.php/t-741227.html that says I must

• determine the cross product of these two vectors (to determine a rotation axis)
• determine the dot product ( to find rotation angle)
• build quaternion (not sure what this means)
• the transformation matrix is the quaternion as a 3 by 3 ( not sure)

Any help on how I can solve this problem would be appreciated.

-
This may be helpful: gamedev.stackexchange.com/questions/20097/… –  Michael Boratko Aug 8 '12 at 21:21
I know it's not your main concern right now, but I suspect it will become a concern later: There's no reason to expect that after applying an arbitrary rotation aligning the normals the triangles will be related by a translation -- you'd still have to rotate around the normal to align them. Stated differently, it's not clear that aligning the normals is a good first step, since you then have to perform two separate rotations. You can get the axis of the full rotation by taking the cross-product of the changes in the differences between two pairs of vertex positions. –  joriki Aug 9 '12 at 5:13
That is a very good point I had not even though of that –  user1084113 Aug 9 '12 at 14:23
@user1084113: No, that would be the cross-product of the changes in two vertex positions; I was talking about the cross-product of the changes in the differences between two pairs of vertex positions, which would be $((A-B)-(A'-B'))\times((B-C)\times(B'-C'))$. This gives you the axis of rotation (except if it lies in the plane of the triangle) because the translation drops out due to the differences, so this is purely the change in two different vectors due to rotation. The translation wouldn't drop out in your version. –  joriki Aug 10 '12 at 13:51
@user1084113: There's no canonical answer to that question. An orientation-preserving isometry of $\mathbb R^3$ can be written as a composition of a rotation and a translation (in either order), but this decomposition is not unique -- you can shift the rotation axis and compensate by performing a different translation. Thus you can only determine the direction of the axis from the data, not its position. You can choose the position arbitrarily, e.g. through the origin, and choose the translation accordingly. –  joriki Aug 10 '12 at 14:33

Here's how to find the transformation from one triangle to another.

First triangle has vertices $a,b,c$ and normal $n$ and second triangle has vertices $a',b',c'$ and normal $n'$.

First we will find transformation $f(x)=Mx+t$ from reference triangle to the first triangle and another transformation $g(x)=M'x+t'$ from reference triangle to the second triangle. Then the transformation mapping first triangle to the second is $$T(x) = g(f^{-1}(x)) = M'(M^{-1}(x-t)) + t' = Rx + s$$ where $R = M'M^{-1}$ and $s = -M'M^{-1}t + t'$.

As the reference triangle we will use triangle with vertices $(0,0,0),(1,0,0),(0,1,0)$ and normal $(0,0,1)$

Then: $$M = [ b-a, c-a, n]$$ $$t = a$$ $$M' = [ b'-a', c'-a', n' ]$$ $$t' = a'$$

You have to be cautious and give vertices $a,b,c$ and $a',b',c'$ in right order. This has to satisfy $((b-a)\times (c-a))\cdot n > 0$ and the same for second triangle.

If those two triangles are not the same then matrix $R$ will not be orthogonal. But we can find isometry which maps one triangle to the another as close as possible in some sense. For this you can use Kabsch algorithm which is well explained here.

-

Suppose you want to find a rotation matrix R that rotates unit vector a onto unit vector b.

Proceed as follows:

Let v = a cross b

Let s = ||v|| (sine of angle)

Let c = a dot b (cosine of angle)

Then the rotation matrix R is given by:

R = I + [v] + [v]^2*(1-c)/s^2,

where [v] is the skew-symmetric cross-product matrix of v.

-

Use Rodrigues' rotation formula (See the section "Conversion to rotation matrix"). $\cos\theta$ is the dot product of the normalised initial vectors and $\sin\theta$ can be determined from $\sin^2\theta + \cos^2\theta =1$

-

You can easily do all this operation using the following reusable library

Vector3 Lib

The following four steps worked for me.

         Vector3 axis = Vector3.CrossProduct(v1, v2);

if (axis.Magnitude != 0)
{
axis.Normalize();
Vector3D vAxis = new Vector3D(axis.X, axis.Y, axis.Z);
Matrix3D m = Matrix3D.Identity;
Quaternion q = new Quaternion(vAxis, AngleFromZaxis);

m.RotateAt(q, centerPoint);
MatrixTransform3D mT = new MatrixTransform3D(m);

myModel.Transform = group;
}


Hope this helps !

With Regards, Shan

-

At the top of my head (do the checking yourself) Let the given vectors in $R^3$ be $A$ and $B$, for simplicity assume they have norm 1, and assume they are not identical. Define $C$ as the cross product of $A$ and $B$. We want an orthogonal matrix $U$ such that $UA=B$ and $UC=C$. First change bases, to the new base $(U_1,u_2,u_3)=(A,B,C)$. In this new basis the matrix doing the job is simply $G=\left(\begin{smallmatrix} 0&1&0\\1&0&0\\0&0&1\end{smallmatrix}\right)$. Then we need the basis shift matrix, to the new basis. Write the coordinates of the vectors in the old base as simply $A=(a_1,a_2,a_3), B=(b_1,b_2,b_3), C=(c_1,c_2,c_3)$. Then the basis shift matrix can be seen to be $\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}$. The result is now simply $U=F^{-1} G F$, which is an orthogonal matrix rotating $A$ into $B$.

-
Actually, I think there may be further trouble - your matrix $U$ is only guaranteed to be orthogonal if $F$ is, which is only the case if $A$ and $B$ are orthogonal. In other instances, the angles of various other vectors to which $U$ is applied may be stretched or compressed. –  Michael Boratko Aug 9 '12 at 19:21
Your thought process is a good one, though - don't give up on it yet! I think there is a solution this way if you consider different original basis vectors which still have an easily represented form of $A$ and $B$. You could, for instance, choose the projection of $A$ on $B$, the rejection of $A$ on $B$, and $A \times B$. –  Michael Boratko Aug 9 '12 at 19:50