Calculate Rotation Matrix to align Vector $A$ to Vector $B$ in $3D$?

380.8k Views Asked by At

I have one triangle in $3D$ space that I am tracking in a simulation. Between time steps I have 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 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 \times 3$ (not sure)

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

3

There are 3 best solutions below

2
On

The quaternion is a $4$-dimensional complex number: http://en.wikipedia.org/wiki/Quaternion used to describe rotations in space. A quaternion (like a complex number) has a polar representation involving the exponential of the arguments (rotations), and a magnetude multiplier. Building the quaternion comes from the cross product (the product of the complex components), which will give you the argument in those $3$ dimensions, you'll then get a number from that in the form $A+Bi+Cj+Dk$, and write it out in the matrix form described in the article there.

An easier way would be to simply fingure out what your original vectors are in the $4$-space, and take the appropriate inverse operations to get your resultant quaternion (without going through the dot/cross product steps) but that requires a good foundation in hypercomplex algebra.

3
On

From the top of my head (do the checking yourself)

  1. Let the given vectors in $R^3$ be $A$ and $B$. For simplicity assume they have norm $1$ and are not identical.

  2. Define $C$ as the cross product of $A$ and $B$. We want an orthogonal matrix $U$ such that $UA=B$ and $UC=C$.

  3. First change bases into 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)$.

  4. 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}$.

  5. The result is now simply $U=F^{-1} G F$, which is an orthogonal matrix rotating $A$ into $B$.

2
On

You can easily do all this operation using the Vector3 library.

The following four steps worked for me.

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

if (axis.Magnitude != 0)
{
    axis.Normalize();
    double AngleFromZaxis = Vector3D.AngleBetween(new Vector3D(0, 0, 1), vAxis);
    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);

    group.Children.Add(mT);

    myModel.Transform = group;
}