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. – Maik Semder Jan 25 '13 at 16:52
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 Jan 25 '13 at 18:11
You're very welcome :) – Maik Semder Jan 25 '13 at 18:24

The rotation-axis is not the z-axis, it is the cross product of the normal of the triangle and the z-axis:

``````rot_axis = normalize(cross(axis_z, triangle_normal))
``````

the rot_angle that you already calculated:

``````rot_angle = acos(dot(axis_z, triangle_normal))
``````

Now we have the Axis-Angle of the rotation. You can convert it to a matrix using Matrix4x4::CreateFromAxisAngle

-