Home | Log In | Contact | Keep Me Posted | Public Meshes | Source Code | Articles | API & Applications |

Projects that do 3d graphics are full of little things that need to be done; this thing has to be positioned there, that thing has to be rotated so it lines up there, and the like.

Conceptually all of these are simple problems. "Oh, you just rotate and move this thing so that this point lines of with that position".
And then you sit down to type and stare blankly into space, wondering how *exaclty* you are supposed to perform this action.

The Meshola project has been full to the brim of just such mysteries, the latest being how do you take a plane that is positioned in 3D space at arbitrary location and rotate it so that it is positioned in a particular way in the normal XYZ axis? Well, um, you rotate it! Use quaterniions! You apply a matrix transform!

I found lots of links on the subject, but they used math that I couldn't comprehend because the symbology was alien. I finally found this paper , which revealed the contents of the matrix to use. The short answer is that the matrix is composed of the dot product of the different axis that you're trying to convert to and from.

In order to save some pain for the next developer I posted some C# in GitHub that has a working sample. The program was derived from one that I found on Code Project , which was written to demonstrate using quaternions but which I found to be useful as a ready-to-go program that would let me rotate and display a surface.

If you want to see what's under the hood here is the essential code. This doesn't show the actual transformation, that's in the code, but the secret sauce of how to do it is located here.

Vector3d X1 = XAxisWorld; // This is vector (1,0,0) Vector3d X2 = YAxisWorld; // This is vector (0,1,0) Vector3d X3 = ZAxisWorld; // This is vector (0,0,1) // These vectors are the local X,Y,Z of the rotated object Vector3d X1Prime = XAxisLocal; Vector3d X2Prime = YAxisLocal; Vector3d X3Prime = ZAxisLocal; // This matrix will transform points from the rotated axis to the world LocalToWorldTransform = new Matrix3x3() { M11 = (float)Vector3d.DotProduct(X1, X1Prime), M12 = (float)Vector3d.DotProduct(X1, X2Prime), M13 = (float)Vector3d.DotProduct(X1, X3Prime), M21 = (float)Vector3d.DotProduct(X2, X1Prime), M22 = (float)Vector3d.DotProduct(X2, X2Prime), M23 = (float)Vector3d.DotProduct(X2, X3Prime), M31 = (float)Vector3d.DotProduct(X3, X1Prime), M32 = (float)Vector3d.DotProduct(X3, X2Prime), M33 = (float)Vector3d.DotProduct(X3, X3Prime), }; // This matrix will transform points from the world back to the rotated axis WorldToLocalTransform = new Matrix3x3() { M11 = (float)Vector3d.DotProduct(X1Prime, X1), M12 = (float)Vector3d.DotProduct(X1Prime, X2), M13 = (float)Vector3d.DotProduct(X1Prime, X3), M21 = (float)Vector3d.DotProduct(X2Prime, X1), M22 = (float)Vector3d.DotProduct(X2Prime, X2), M23 = (float)Vector3d.DotProduct(X2Prime, X3), M31 = (float)Vector3d.DotProduct(X3Prime, X1), M32 = (float)Vector3d.DotProduct(X3Prime, X2), M33 = (float)Vector3d.DotProduct(X3Prime, X3), };