This post really helped. In this post, this guy david says:
Hi Scott, Here is one possibility: If the old axis is _a_ and the new axis is _a'_, use theta = acos(_a_ dot _a'_) (where 'dot' means dot product) _axis_ = _a_ cross _a'_ (cross product) then RotateWXYZ(theta,axis,axis,axis) will provide the desired rotation. Don't forget to do the radians-to-degrees conversion before calling RotateWXYZ. A much more efficient way to it if the original axis _a_ is always the x axis is to build the matrix yourself. First, you need to find two vectors _b'_ and _c'_ which are perpendicular to _a'_. You can use vtkMath::Perpendiculars() for this if you have a recent version of VTK. Then, build the matrix by inserting the vectors into the matrix columns: a' b' c' t a' b' c' t a' b' c' t 0 0 0 1 where _t_ is the translation you wish to apply after the rotation. - David
I wanna personally thank the dude.
But that wasn’t enough. There was also this post posted by none other than shawn hargreaves. He says:
When you’re working in 3D it’s generally best to avoid thinking in terms of rotations as angles. Trying to extract angle rotations lands you in a world of pain working out complex trig equations, which are not at all my idea of fun! This sort of thing can generally be done much more easily using vector and matrix math.
Ultimately, you want a matrix that describes the rotation of your object, but you can get there from a couple of vectors. One vector alone is not enough to describe a full orientation, though, because that still leaves one axis of freedom that the object could rotate to any angle around that vector.
Let’s start out by choosing a front vector for our orientation: you can get this by normalizing your movement vector.
Now we need vectors pointing right and up. To avoid squashing the object, these need to be perpendicular (at right angles to) to the front vector. We could guess that up might be roughly Vector3.Up, but that might need some adjustment to make it stay perpendicular to our front vector. Here’s how to do that:
– Compute a right vector by taking the cross product of your front vector and Vector3.Up, and normalizing that result
– Compute a properly perpendicular up vector by taking the cross product of the right vector that you just calculated and your front vector.
Now you have three vectors, all perpendicular to each other, that describe the orientation of your object. Turning these into a matrix is simple: start off with Matrix.Identity, then assign your new values to its Forward, Right, and Up properties.
I might have got some of those cross products the wrong way round (I’m terrible at remembering which way they go) so if your model comes out inverted, just swap the order of the arguments to the cross product calls.
The framework actually has a built in method that does almost the same thing as the above, in the Matrix.CreateLookAt method. You could pass Vector3.Zero as cameraPosition, your movement vector as cameraTarget, and Vector3.Up as cameraUpVector, and it will give back almost the same thing as the matrix I described above, only backward. Call Matrix.Transpose on the result, and you can use that for your object orientation.
very helpful indeed. thanks shawn!
Finally for understanding this crap more, the math of viewing matrices, including an explanation of what/how do it.