views:

531

answers:

2

I have a line (actually a cube) going from (x1,y1,z1) to (x2,y2,z2). I would like to rotate it so that it is aligned along another line going from (x3,y3,z3) to (x4,y4,z4). Presently I am using Math::Atan2 along with Matrix::RotateYawPitchRoll. Any better ways to do this?

Edit: I think I've worded this post very badly. What I am actually looking for is a Rotation Matrix from two Vectors.

+3  A: 

Yes you can do this without needing to think in terms of angles at all.

Since you have a cube, suppose you pick one corner and then define the 3 edges radiating out from it as vectors f0, f1, f2 (these are direction vectors, relative to the corner you've picked). Normalise those and write them as columns in a matrix F

(f0x f1x f2x)
(f0y f1y f2y)
(f0z f1z f2z)

Now do the same thing for the vectors t0, t1, t2 of the cube you want to rotate to and call it matrix T.

Now the matrix R = T * Inverse(F) is the matrix which rotates from the orientation of the first cube to the orientation of the second (because inverse F maps e.g f0 to (1 0 0)', and then T maps (1 0 0)' to t0).

If you want to know why this works, think in terms of coordinate system basis vectors: if you want to rotate the X Y and Z axes to a new coordinate system, well the columns of the rotation matrix are just the vectors you want (1 0 0)', (0 1 0)' & (0 0 1)' to be mapped to. T*Inverse(F) is effectively rotating your cube from its original orientation to axis aligned, and then to the desired orientation.

(Sorry, above is for column vectors and transforms on the left, OpenGL style. I seem to remember Direct3D is row vectors and transforms on the right, but it should be obvious how to switch it around).

It also applies equally well to 4x4 matrices with a translation component too.

timday
Actually it is not a cube either. A steel I-section. But this should help. Thanks.
Vulcan Eager
OK. The point is you need to define a local coordinate system... if you just have lines, the rotation is ambiguous.
timday
Thanks, Tim. I did not understand why this should not work for lines.
Vulcan Eager
A: 

You might want to add how to actually interpolate the matrices. Source and destination matrices are fine in your answer, but computing the inverse is pointless. Quaternions will give you the shortest rotational path, so take the rotational 3x3 matrices on both matrices, convert to quaternions and lerp those. Do a separate lerp for the translation and recompose. Google for quaternion - matrix and back conversions and quaternion lerp.

Edit: A rotation matrix from a forward and an up vector is trivial. The missing column is the cross product of the other two vectors. (don't forget to normalize columns).

starmole