3
\$\begingroup\$

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

enter image description here

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.

enter image description here

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;
}
\$\endgroup\$
3
\$\begingroup\$

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

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.