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?
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.