Rotating a point in space

Hello,
I am trying to rotate point p(3,0,0) with a vector dir(1,0,0) to a new direction dir2(0,1,0), wich means a 90º rotation around the z axis. But I’m having a problem with the code bellow wich returns me p2(0.875780;1.363946;-2.524413) instead of p2(0,3,0)… atm I can’t locate the problem… does anyone have any idea?
Thanks

 
CVector p(3,0,0),p2(0,0,0);
CVector dir(1,0,0);
CVector dir2(0,1,0);
float alfa,beta,gama;


alfa=dir.x-dir2.x;
gama=dir.y-dir2.y;
beta=dir.z-dir2.z;

float x,y,z;
float cos_alfa=cos(alfa);
float sin_alfa=sin(alfa);

float cos_beta=cos(beta);
float sin_beta=sin(beta);

float cos_gama=cos(gama);
float sin_gama=sin(gama);

x=p.x;
y=p.y;
z=p.z;

p2.x=x* ( cos_alfa * cos_gama ) + 
y* ( cos_alfa * sin_gama * sin_beta - sin_alfa * cos_beta ) +
z* ( cos_alfa * sin_gama * sin_beta - sin_alfa * cos_beta );

p2.y=x* ( sin_alfa * cos_gama ) + 
y* ( sin_alfa * sin_gama * sin_beta - cos_alfa * cos_beta ) +
z* ( sin_alfa * sin_gama * cos_beta - cos_alfa * cos_beta );

p2.z= -x * sin_alfa + z* ( cos_gama * sin_beta );

printf("Table:

");
printf("Pos p(%f;%f;%f)
",x,y,z);
printf("Dir v(%f;%f;%f)
",dir.x,dir.y,dir.z);
printf("Dir v2(%f;%f;%f)

",dir2.x,dir2.y,dir2.z);

printf("Alfa: %f
",alfa);
printf("Gama: %f
",gama);
printf("Beta: %f

",beta);

printf("Pos p2(%f;%f;%f)

",p2.x,p2.y,p2.z); 

Rotating about the z-axis only is very simple, rotating about an arbitrary axis is very slightly more difficult, here I’ll explain both.

If our point is P = (x, y, z) then obviously z doesn’t change in a z-axis rotation. So we just need a simple 2D rotation which is:

x’ = x * cos(theta) - y * sin(theta)
y’ = x * sin(theta) + y * cos(theta)
z’ = z

An alternative way to think about this rotation is in terms of vectors, where our rotated point becomes:
P’ = cos(theta) * OP + sin(theta) * N
Where N is the anti-clockwise normal, in the Z=z plane, to the vector from the origin to P (called OP). You can compute this simply as N = (-y, x, z).

If we stick in (3, 0, 0) and theta = PI / 2 = 90 degrees then,
P’ = cos(PI/2) * (3, 0, 0) + sin(PI/2) * (0, 3, 0)
cos(PI/2) = 0 and sin(PI/2) = 1, so we get (0, 3, 0) as expected.

Now if we have any axis S in 3D space and want to rotate a point P about it then we can take the following strategy:

  • Project P onto S, giving P’
  • Compute P’’ = P - P’, P’’ is P projected into
    the plane perpendicular to S.
  • Compute N, the anticlockwise normal to P’’ in the plane perpendicular to S. We can do this using the cross-product
  • Now rotate P’’ about S, using the formula
    P’’’ = P’’ * cos(theta) + N * sin(theta)
    This rotates P’’ about S in the plane defined by S, all we have to do is translate it “up” again, parallel to S.
  • Compute the final result of our rotation
    R = P’’’ + P’

Maybe you already knew how to rotate points about axes, so I’ll also give some simple code, of questionable quality, to do this. Please note this code is optimised only for clarity.

//
// Rotate u about axis by an angle phi
//
void rotate(const Vec3& axis, Vec3& u, float phi)
{
Vec3 v = axis;
v.normalise();
Vec3 proj = axis.dot(u) / axis.dot(axis) * axis;
Vec3 r = u - proj;
Vec3 n = v * r; // cross product
u = proj + (float) sin(phi) * n + (float) cos(phi) * r;
return;
}