0

I have a mathematical problem which is part of my 3D game and I can't seem to be able to figure it out.

I have two three-dimensional vectors a and b and I need to calculate such a rotation matrix that would align a to have the same direction as b. I need to use this matrix afterward to calculate the resulting position of other points in 3D space.

I have found some solutions for this problem here, but I either was not able to comprehend the mathematics involved with my limited knowledge or the problem actually different in some way from mine (like being in 2D space).

I am writing the program in C# which already has a 4 by 4 matrix class with utility methods like CreateRotationX, which I would love to utilize. The problem is to find the appropriate angle size for each axis.

I tried to "look" at the vectors in a perpendicular direction to each axis, hence basically transforming the vectors to 2D and then calculating the angle. That however did not work and I suspect it has to do with the angle orientation (- vs. +).

Here is the snippet I am using to get the matrices:

var aX = new Vector2(vectorA.Y, vectorA.Z);
var bX = new Vector2(vectorB.Y, vectorB.Z);
var rotationX = Matrix4x4.CreateRotationX((float)aX.AngleTo(bX));

var aY = new Vector2(vectorA.X, vectorA.Z);
var bY = new Vector2(vectorB.X, vectorB.Z);
var rotationY = Matrix4x4.CreateRotationY((float)aY.AngleTo(bY));

var aZ = new Vector2(vectorA.X, vectorA.Y);
var bZ = new Vector2(vectorB.X, vectorB.Y);
var rotationZ = Matrix4x4.CreateRotationZ((float)aZ.AngleTo(bZ));

Where AngleTo method is as follows:

public static double AngleTo(this Vector2 from, Vector2 to)
{
    var dotProduct = from.X * to.X + from.Y * to.Y;
    var determinant = from.X * to.Y - from.Y * to.X;
    return Math.Atan2(determinant, dotProduct);
}

Could you please point me in the right direction to find a solution to this problem?

  • Checkout this post: https://math.stackexchange.com/questions/293116/rotating-one-3d-vector-to-another – David Jun 20 '19 at 20:39
  • I have seen that post but I am confused by the fact that it uses a 3x3 matrix, not 4x4. If I understood correctly, for affine transforms in 3D we need to use a 4x4 matrix, or not? – Martin Zikmund Jun 21 '19 at 10:41
  • For a rotation of vectors all you need is a $3\times 3$ matrix. The extra row and column in your matrix allow objects to be moved by translation, or to be rotated around a point other than the origin. Neither of those operations is meaningful for vectors. Most software that uses $4\times4$ matrices gets them by taking the $3\times3$ rotation matrix and adding a column on the right and a row on the bottom. – David K Jun 21 '19 at 11:32
  • Also, most software that does rotations will let you construct the matrix using an arbitrary axis of rotation and a single rotation angle around that axis. You don't need Euler angles. – David K Jun 21 '19 at 11:38

1 Answers1

2

There is no unique solution. For simplicity, say vectors $\vec a$ and $\vec b$ have length of $1$ (otherwise just divide each one by its length). Furthermore, assume that the two vectors are not parallel or antiparallel. There are two basic rotations that you can use. One has the axis perpendicular the the plane of two vectors. Both the axis and the angle are given by the cross product. The axis of rotation is $$\hat n_\perp=\frac{\vec a\times\vec b}{|\vec a\times\vec b|}$$ The rotation angle $\theta$ from $\vec a$ to $\vec b$ is given by $$\sin\theta=\frac{|\vec a\times\vec b|}{|\vec a||\vec b|}=|\vec a\times\vec b|$$ The other obvious option is to take the bisecting vector as the axis of rotation ($\hat n_b=\frac{\vec a+\vec b}{|\vec a+\vec b|}$) and rotate by $\pm\pi$. It is easy to show now that you can choose any direction in the plane of $(\hat n_\perp,\hat n_b)$ as your axis of rotation. Then $vec a$ and $\vec b$ are on a cone with the axis as your chosen one, and you can determine the rotation angle.

Andrei
  • 37,370