Rotating 3d plane to XY plane

I have a triangle in 3d space and would like to create a grid over the triangle, such as in the image below.

The purpose of this is to store information about each block of the grid. In order to store this grid in a 2D array, my idea was to rotate the triangle until it is in the XY plane. After rotation the above triangle would look like the image below.

What I have tried to do is find the angle between the triangle's normal and the z-axis, then rotate each vertex by this amount.

    public double getAngle(Vector3 normal, Vector3 axis) {
double dot = normal.dotProduct(axis);
double angle = Math.acos(dot / (normal.getMagnitude() * axis.getMagnitude()));
System.out.println("angle = " + Math.toDegrees(angle));
return angle;
}

public static void main(String args[]) {
Vector3 pointA = new Vector3(0,0,0);
Vector3 pointB = new Vector3(5,5,5);
Vector3 pointC = new Vector3(-5,5,5);
Triangle tri = new Triangle(new Vector3[]{pointA, pointB, pointC});
Vector3 normal = tri.normal();
normal.normalize();
Vector3 zAxis = new Vector3(0, 0, 1);
Matrix4x4 rot = Matrix4x4.getRotationMatrix(0, 0, patch.getAngle(normal, zAxis));
for(int i = 0; i < tri.vertices.length; i++) {
tri.vertices[i] = rot.multiply(tri.vertices[i]);
}
}


The result of this code would be:

Triangle's normal: (0.0, -50.0, 50.0)
Normalized normal: (0.0, -0.7071067811865475, 0.7071067811865475)
Vertices after rotation:
(0.0, 0.0, 0.0)
(4.440892098500626E-16, 7.0710678118654755, 5.0)
(-7.0710678118654755, 4.440892098500626E-16, 5.0)


This is not quite right, though. I am expecting all z-coordinates to be the same so that I can ignore them and store the grid in a 2d array. Is there something else I need to do to rotate the triangle appropriately, or is there a simpler way to store this grid? If needed, the code for my rotation matrix is below:

private static Matrix4x4 getRotationMatrix(double x, double y, double z, boolean inverse) {
double sign = (inverse) ? -1 : 1;
Matrix4x4 rotateX = new Matrix4x4(new double[][]{
{1, 0,             0,            0},
{0, Math.cos(sign * x), -Math.sin(sign * x), 0},
{0, Math.sin(sign * x),  Math.cos(sign * x), 0},
{0, 0,             0,            1}
});
Matrix4x4 rotateY = new Matrix4x4(new double[][]{
{ Math.cos(sign * y), 0, Math.sin(sign * y), 0},
{ 0,            1, 0,            0},
{-Math.sin(sign * y), 0, Math.cos(sign * y), 0},
{ 0,            0, 0,            1}
});
Matrix4x4 rotateZ = new Matrix4x4(new double[][]{
{Math.cos(sign * z), -Math.sin(sign * z), 0, 0},
{Math.sin(sign * z),  Math.cos(sign * z), 0, 0},
{0,             0,            1, 0},
{0,             0,            0, 1}
});
Matrix4x4 rotation = rotateZ.multiply(rotateY).multiply(rotateX);
return rotation;
}

• The problem is the rotation around the z-axis. The triangle must be rotated around rot_axis = cross(tri_normal, z_axis), not around the z-axis. Commented Jan 25, 2013 at 16:52
• See my answer here for details. Either use quaternions as in my answer, or convert the rotation-axis and the rotation-angle (axis-angle) to a matrix using Matrix4x4::CreateFromAxisAngle Commented Jan 25, 2013 at 16:58
• Thank you! I went with the Matrix4x4 solution and it worked great. Do you want to write an answer that I can accept?
– A D
Commented Jan 25, 2013 at 18:11
• You're very welcome :) Commented Jan 25, 2013 at 18:24

rot_axis = normalize(cross(axis_z, triangle_normal))

rot_angle = acos(dot(axis_z, triangle_normal))