TonyLic
TonyLic

Reputation: 667

How to rotate a vector to a place that is aligned with Z axis?

I want to rotate a vector to the Z axis and its direction is Z-axis backward. So if the vector is (1,1,1), my result should be (0,0,-sqrt(3)).

My idea is two steps. The first step is to rotate my vector around X axis to the XZ plane. The second step is to rotate the vector in the XZ plane around Y axis to Z axis.

Here is my code:

GLfloat p[4] = {1,1,1,0}; //my vector, in homogeneous coordinates
GLfloat r[4]; //result vector to test

float theta1 = ((double)180/PI)*asin(p[1]/sqrt(p[0]*p[0]+p[1]*p[1]+p[2]*p[2])); 
//angle theta1 between the vector and XZ plane, is this right ??? I doubt it !!!
float theta2 = ((double)180/PI)*atan(p[0]/p[2]); 
//angle theta2 between the vector's projection in XZ plane and Z axis 

GLfloat m[16]; 
glMatrixMode(GL_MODELVIEW); // get the rotation matrix in model-view matrix
glPushMatrix();
glLoadIdentity();
glRotatef(theta1, 1,0,0); //rotate to the XZ plane
glRotatef(180-theta2,0,1,0); //rotate to the Z axis
glGetFloatv(GL_MODELVIEW_MATRIX, m); // m is column-major.
glPopMatrix();

// use the matrix multiply my vector and get the result vector r[4]
//my expectation is (0,0,-sqrt(3))
r[0] = p[0]*m[0]+p[1]*m[4]+p[2]*m[8]+p[3]*m[12];
r[1] = p[0]*m[1]+p[1]*m[5]+p[2]*m[9]+p[3]*m[13];
r[2] = p[0]*m[2]+p[1]*m[6]+p[2]*m[10]+p[3]*m[14];
r[3] = p[0]*m[3]+p[1]*m[7]+p[2]*m[11]+p[3]*m[15]; 

However, the result r[4] is not my expectation. So I think I made some mistakes in some places above. Could anyone give me a hint about that ?

Upvotes: 2

Views: 9236

Answers (1)

Alnitak
Alnitak

Reputation: 339796

To rotate one vector so it faces another:

  1. normalise it
  2. take their dot product to get the cosine of the rotation angle
  3. take their cross product to find an orthogonal rotation vector
  4. rotate around that new vector by the angle found in #2

Step 2 can be omitted if you remember that | A x B | = sin(theta) if A and B are both normalised.

Upvotes: 9

Related Questions