I am writing an OpenGL program and I need to align one vector with another one. I am currently using the cross product of the two vectors as an axis of rotation. I rotate about that axis by the angle between them and they line up fine. My problem is the resulting transform has an arbitrary twist around the target vector. Does anyone know how to control the twist? I think some concept of an “up vector” would help but I am at my wits end trying to find it / figure it out. Any Ideas?
Yea, this happens
if you define:
v1 = original vector
v2 = target vector
M = rotation matrix used to rotate v1 to v2
u1 = up vector
u2 = rotated up vector = M * u1
After you rotate v1 to v2, you need to do a second rotation. This time, your axis will be v2 and your angle will be the angle between u1 and u2.
I tried adding the extra rotation you recommended but I still experience twist. I am trying to align the vector V1 (1, 0, 0) with vector V2 that is being animated. As V2 approaches (-1, 0, 0), the cross product of V1 and V2 appears to suffer from numerical instability that results in twist. Any suggestions?
Doh! I didn’t forsee that. Could you maybe check if the dot product is within epsilon of -1 (or that the angle is within epsilon of PI) and then if it is, instead of rotating just scale by (-1, -1, -1) ?
I know this is a hack, but it should work until I can think of a more general solution
What you have:
Vector V1, pointing in some direction.
Vector V2, pointing in some direction.
What you want is:
Vector V2’, pointing in the same direction as V1, with the length of V2.
It seems to me that the easiest way of doing this is to make:
V2’ = V1 * length(V2) / length(V1)
No cross products, no rotations, nothing fancy.
What I am actually looking for is a matrix that rotates v1 so that it is aligned with v2 (v1 and v2 are both unit vectors).
I have adjusted my algorithm (i am modeling windy tree branches) in such a way that avoids this problem. I am still very curious to know how this problem can be solved in a general case. Thanks for all of your help!
Could you be a bit more specific about what you mean by twist? Do you mean that you are rotating one coordinate frame to another and one vector matches, but the other two do not?
If this is your problem, you should look at the frames of orientation as quaternions or matrices rather than a single vector. If you do this, then the math is as follows:
O1 - Orientation #1
O2 - Orientation #2
To transform from O2 to O1:
O1 * Inv(O2)
The problem with saying “rotating one vector to another” is that you’re not constraining “up” vectors for the source or destination vectors, i e there’s an infinite number of matrices that will rotate V2 to point in the direction of V1.
Treating the input data as orientations (quaternions or axis/angle or rotation matrices or vectors with up vectors) is necessary to solve the problem correctly.
The algorithm adjustment I mentioned earlier was using matrices to represent orientations throughout the tree. That is working great and I am grateful for all of the help you have given me.