# from normal to rotation matrix

(i'm on OPENGL)

i have a mesh O (object) and a mesh T (terrain). i know a single triangle in T and i want to orient O to be aligned to that triangle (torate O to align to T in that point).

i have only the normal in the triangle. how can i achive the roation matrix?

i have thought this algorithm:

// pseudocode
float[] normal2rotation(Vector3D normal) {
angleX = Vector3D.angleBetween(normal, Vecto3D.Axis3D.X);
angleY = Vector3D.angleBetween(normal, Vecto3D.Axis3D.Y);
angleZ = Vector3D.angleBetween(normal, Vecto3D.Axis3D.Z);

float[] result = {angleX, angleY, angleZ};
return result
}


but it does not give me the desired result.

The easiest way to do this is to directly build a rotation matrix to accomplish the desired transform. If you need to convert it to a quaternion or Euler angles afterward, you can do that using the standard conversions.

Since you're in OpenGL I'll assume you're using column vectors. In that case, with a 3x3 rotation matrix, the first, second and third columns are the vectors to which the X, Y, and Z axes will be taken by the matrix. Therefore, if you want to rotate an object so that its Z axis points along the normal, you would set the third column of the matrix to the normal, and find two perpendicular vectors in the plane of the triangle to use for the first and second columns.

Something like this (I don't know your libraries, so I'm guessing at the syntax):

Matrix NormalToRotation(Vector3D normal) {
// Find a vector in the plane
Vector3D tangent0 = Cross(normal, Vector3D(1, 0, 0));
if (Dot(tangent0, tangent0) < 0.001)
tangent0 = Cross(normal, Vector3D(0, 1, 0));
tangent0 = Normalize(tangent0);
// Find another vector in the plane
Vector3D tangent1 = Normalize(Cross(normal, tangent0));
// Construct a 3x3 matrix by storing three vectors in the columns of the matrix
return ColumnVectorsToMatrix(tangent0, tangent1, normal);
}

• mhmm sorry i'm using a wrapper under opengl so i'm bit higher that simple opengl, why column vector? – nkint Jan 10 '12 at 20:37
• Because that's the convention typically/traditionally used with OpenGL. However, if your math library is using a row vector convention, that's fine, just replace "column" with "row" everywhere. – Nathan Reed Jan 10 '12 at 21:18

There are an infinite number of possible orientations that will orient 'O' to 'T'. A single vector ('T's normal) isn't enough since 'O', once aligned with the normal can rotate freely about that normal and still meet the criteria... a second vector is needed to lock it in a specific orientation, perhaps another known direction 'O' is pointing?

The crossing that is needed (as Nathan's post demonstrates) to find the other to matrix basis vectors should start with a cross between the normal & that 2nd direction vector.