Rotation around an vector in C#/XNA

This post show how you can rotate one vector around a arbitrary axis, represented by a second vector. This is done by defining a rotation matrix.

I was playing around with the Microsoft XNA framework, and needed a way to rotate a vector around a second vector. Now I know that the framework probably include functions to do that, but I thought that I would look into the thing myself, and implement my own custom rotation. This may be basic math to some, but not to me, and I thought that I would share the way to accomplish this.

First of all, you’ll need is a vector v = (x, y, z) and an axis of rotation a = (X, Y, Z). You will also need an angle of rotation r, measured in radians. By using a negative angle, you can rotate clockwise.

So what we want to do, is to rotate the vector v r radians around the axis a. The result is another (rotated) vector vr.  The way to do this, is by creating a “rotation matrix” A based on the axis a and the angle r, and then multiply matrix with the vector v. The result is a rotated vector.

Sound complicated – let me explain:

The rotation matrix is simply a table of numbers, 3×3:

Rotation matrix

We need to perform the multiplication Av, that is multiply the rotation matrix with the original vector. The way to do this is by matrix multiplication, that is by multiplying each row of the rotation matrix with the value of the original vector:

Cross product between rotation matrix and vector
Definition of cross product

So you simply have to calculate the nine values of the rotation matrix, and multiply then on the x, y and z values of the original vector, and voila, you got the 3 coordinates of the rotated vector. Unfortunately, these nine values require some work (remember that X, Y and Z are the coordinates of the axis):

a1 = (t(r) * X * X) + cos(r)
a2 = (t(r) * X * Y) - (sin(r) * Z)
a3 = (t(r) * X * Z) + (sin(r) * Y)
b1 = (t(r) * X * Y) + (sin(r) * Z)
b2 = (t(r) * Y * Y) + cos(r)
b3 = (t(r) * Y * Z) - (sin(r) * X)
c1 = (t(r) * X * Z) - (sin(r) * Y)
c2 = (t(r) * Y * Z) + (sin(r) * X)
c3 = (t(r) * Z * Z) + cos (r)

The function t(r) is defined by t(r) = 1-cos(r).

Phew – at least the computer is going to do the work!

Now all we need to do is to express this math in C#, e.g. like this: rotate.cs [3kb]

4 responses to “Rotation around an vector in C#/XNA”

  1. Rakshak Avatar
    Rakshak

    great job there sir
    is there an inbuilt function for this operation..(i.e to rotate along another vector)

  2. Mayur Avatar
    Mayur

    Thats an excellent post.. However i would like to know wht i’ll changes wld i have to make to make it work for a 2-D matrix.
    What i need is the implementation of Matrix.Rotate() method of WPF in Silverlight, since silverlight does not have any inbuilt method for matrix rotation.

  3. Kristoffer Brinch Kjeldby Avatar

    Here is some psedo code:

    Vector 2D Rotate(Vector2D p, Vector2D o, Degrees d)
    {
      var r = new Vector2D();
      r.X = o.X+cos(d)*(p.X-o.X)
            -sin(d)*(p.Y-o.Y);
      r.Y = o.Y+sin(d)*(p.X-o.X)
            +cos(d)*(p.Y-o.Y);
     return r;
    }

    p is the vector you want to rotate, o is the center around which you want to rotate and d is the degrees.

    You can read more here: http://gpwiki.org/index.php/VB:Rotating_A_Point_In_2D