Search code examples
c#vectorxnarotation

Rotation axis to perform rotation


Having a first-person camera looking at direction d.

In order to let the camera point to a target t (with associated direction d2) I would have to rotate d around some axis, right ? This axis should go through the camera and should be perpendicular to the plane formed by d and d2, right ?

Suppose I am rotating the vector d by some degree per frame the rotation axis shouldn't change because though d is slowly approaching d2 their corresponding plane doesn't change, right ?

Well, if that's all true then I am wondering why my rotation axis in the below example is changing on every call. The rotation works accurate but the speed decreases from start of the rotation to its end.

This post is from the context of a current question here where you can also see the source code.


Solution

  • The direction _rotationAxis points in is not changing thus direction of rotation as you state is constant and correct. But The magnitude of _rotationAxis is changing thus you get different values for the x, y, z components and a different rotation amount.

    When you perform a cross to get a rotational axis, the length of the resulting vector is a function of the lengths of the two vectors that were crossed AND the angle that separates them. The direction of the resulting vector is always 90 degrees to both of the two inputted vectors.

    Most likely, the lengths of the 2 vectors you are using is consistent and most likey unit length but since the angle between them less each frame, it results in a different length for _rotationAxis each frame.

    In Xna, the resulting amount of rotation produced from CreateFromAxisAngle is determined by not only the angle you plug into is as a parameter, but also the length of the axis vector (not obvious in the documentation but true none the less). So you are using a shorter and shorter rotational axis each frame which causes a smaller and smaller amount of rotation each frame. It will only result in the rotational angle you plugged in if the rotation axis vector's length is 1.0 (a unit length vector).

    You must normalize the _rotationAxis to make it unit length before using it in CreateFromAxisAngle .

    _rotationAxis = Vector3.Cross(Direction, _flyTargetDirection);
    _rotationAxis.Normalize();
    _rotation = Matrix.CreateFromAxisAngle(_rotationAxis, MathHelper.ToRadians(_flyViewingSpeed - Math.ToRadians(rotationSpeed)));