# Rotate a vector

I want my first-person camera to smoothly change its viewing direction from direction d1 to direction d2. The latter direction is indicated by a target position t2.

So far I have implemented a rotation that works fine but the speed of the rotation slows down the closer the current direction gets to the desired one. This is what I want to avoid.

Here are the two very simple methods I have written so far:

``````// this method initiates the direction change and sets the parameter
public void LookAt(Vector3 target) {

_desiredDirection = target - _cameraPosition;
_desiredDirection.Normalize();

_rotation = new Matrix();

_rotationAxis = Vector3.Cross(Direction, _desiredDirection);

_isLooking = true;
}

// this method gets execute by the Update()-method if _isLooking flag is up.
private void _lookingAt() {

dist = Vector3.Distance(Direction, _desiredDirection);

// check whether the current direction has reached the desired one.
if (dist >= 0.00001f) {

_rotationAxis = Vector3.Cross(Direction, _desiredDirection);
_rotation = Matrix.CreateFromAxisAngle(_rotationAxis, MathHelper.ToRadians(1));

Direction = Vector3.TransformNormal(Direction, _rotation);
} else {

_onDirectionReached();
_isLooking = false;
}
}
``````

Again, rotation works fine; camera reaches its desired direction. But the speed is not equal over the course of movement -> it slows down.

How to achieve a rotation with constant speed ?

-

``````_rotationAxis = Vector3.Cross(Direction, _desiredDirection);
_rotation = Matrix.CreateFromAxisAngle(_rotationAxis, MathHelper.ToRadians(1));
``````

As `Direction` & `_desiredDirection` change to be pointing in nearly the same direction (as they converge), The smaller the magnitude of `_rotationAxis` will be. It will still be pointing in the proper direction to be the axis but will be a shorter length. That is the nature of the cross calculation.

The guts of the `CreateFromAxisAngle` method uses the length of the axis as a factor in the amount of rotation it results in. When the axis has a length of 1, it results in the correct amount of rotation.

So if you were to normalize `_rotationAxis` between the two lines I quoted above, you would get a constant rotational rate.

-

I'd suggest letting the framework do all of the work for you. Start by calculating a rotation matrix for your start and end orientations, and convert them both to quaternions. You only do this once at the start of the movement and store the values.

``````Matrix start = /* calculate current rotation matrix */;
Matrix end = /* calculate desired rotation matrix */;
Quaternion startQ = Quaternion.CreateFromRotationMatrix(start);
Quaternion endQ = Quaternion.CreateFromRotationMatrix(end);
``````

Now interpolate between these two orientations using spherical linear interpolation. There's a method for it so you don't have to implement anything yourself:

``````// Animate the progress parameter between 0 and 1
Quaternion currentQ = Quaternion.Slerp(startQ, endQ, progress);
``````

Finally recalculate your direction using the quaternion above, or convert it back to a rotation matrix. Something like this for instance:

``````Vector3 direction = Vector3.Transform(Vector3.Forward, currentQ);
``````
-
Thank you very much for your detailed advise! I will try that after lunch ;) – marc wellman Oct 9 '12 at 11:20
`Quaternion.Slerp` Is it just me, or does that sound like a name in either a really bad or really good fantasy novel? Minus the dot, of course. – QPaysTaxes Jan 15 '15 at 19:47