Search code examples
javamatrix3drotationquaternions

Can't Correctly rotate 3D Point A to B (on X, Y, Z axis)


I has tirelessly been researching for three weeks now, each and every procedure for rotating a 3D Point 'A' to 3D Point 'B', the following are the techniques I attempted with no success:

  • Rotation Matrix
  • Euler Angles to Rotation Matrix
  • Axis Angle to Rotation Matrix
  • Quaternion Coordinate Rotation
  • Trigonometry Multiple Axis Rotation

I would like to perform a simultaneous 3d 3 axis (so, X, Y, Z) rotation in java (please know I don't particularly understand the mathematics behind it, I would prefer the answer to be in java code, with the example I displayed).

e.g. 
Pointf a = new Pointf(0f, 2f, 0f);
Pointf b = new Pointf(2f, 0f, 2f);

// ~~~ Start of Rotation Matrix ~~~

// azimuth (Z Axis)
float azimuth = (float) Math.toRadians(90f);
// elevation (Y Axis)
float elevation = (float) Math.toRadians(0f);
// tilt (X Axis)
float tilt = (float) Math.toRadians(90f);

/*
public static Matrix4x4f createRotationMatrix(double azimuth, double elevation, double tilt) {
        // Assuming the angles are in radians.
        //Precompute sines and cosines of Euler angles
        double su = sin(tilt);
        double cu = cos(tilt);
        double sv = sin(elevation);
        double cv = cos(elevation);
        double sw = sin(azimuth);
        double cw = cos(azimuth);

        //Create and populate RotationMatrix
        Matrix4x4f A = Matrix4x4f.create();
        A.values[0] = (float) (cv*cw);
        A.values[1] = (float) ((su*sv*cw) - (cu*sw));
        A.values[2] = (float) ((su*sw) + (cu*sv*cw));
        A.values[4] = (float) (cv*sw);
        A.values[5] = (float) ((cu*cw) + (su*sv*sw));
        A.values[6] = (float) ((cu*sv*sw) - (su*cw));
        A.values[8] = (float) -sv;
        A.values[9] = (float) (su*cv);
        A.values[10] = (float) (cu*cv);      

        return A;
    }
*/

// Multiplies the Z * Y * X Rotation Matrices to form 'Matrix4x4f m' 
Matrix4x4f m = Matrix4x4.createRotationMatrix(azimuth, elevation, tilt);

// Multiple point 'a' with Matrix4x4f 'm' to get point 'b'
m.transform(a); // Should return {2, 0, 2} same 'b', but returns {2, 0, 0}

// ~~~ End of Rotation Matrix ~~~

FYI. My main source of information was from the following:

http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToMatrix/index.htm

Thanks All


Solution

  • I can explain an algorithm for finding the matrix of rotation, though I don't have code for it.

    Every rotation is around an axis. I assume that you want an axis that goes through the origin O. In that case, the rotation takes place in the plane defined by the three points O, A, and B. As the rotation axis, you can use the vector which is the cross product of the two vectors OA and OB. Here is the formula.

    enter image description here

    Let's call the three components of this direction vector for the axis (u,v,w), for simplicity (and we'll assume its normalized). Next find the angle theta between OA and OB, this is found by the standard formula for the angle between two vectors.

    Finally, the hard part is done for you at this site, which links to the following 3D matrix of rotation about the origin, which will rotate A to B. Java code for this matrix can be downloaded at this site.

    enter image description here

    You can check out some rotations interactively here.