3

I'm trying to decompose a homogeneous coordinates transform matrix which is the result of these transformations matrices (applied in their writing order): non-uniform Scale -> Rotate -> Translate I haven't any problem in extracting the translation coordinates from the resulting 4x4 transfor matrix (the first three values of the last column) but I couldn't find a way to extract the rotation and scaling matrices.

I found the following matrix decomposition algorithm on the web:

  1. Compute the scaling factors as the magnitudes of the first three basis vectors (columns or rows) of the matrix
  2. Divide the first three basis vectors by these values (thus normalizing them)
  3. The upper-left 3x3 part of the matrix now represents the rotation (you can use this as is, or convert it to quaternion form)
  4. The translation is the fourth basis vector of the matrix (in homogeneous coordinates - it'll be the first three elements that you're interested in)

Here comes my java implementation

    public void decompose(Vec3 translation, Vec4 rotationAxisAndAngle, Vec3 scale) {
            translation = this.getTranslation();
            Vec3 c0 = new Vec3(values[ 0], values[ 1], values[ 2]);
            Vec3 c1 = new Vec3(values[ 4], values[ 5], values[ 6]);
            Vec3 c2 = new Vec3(values[ 8], values[ 9], values[10]);
            scale.x = Vec3.len(c0.x, c0.y, c0.z);
            scale.y = Vec3.len(c1.x, c1.y, c1.z);
            scale.z = Vec3.len(c2.x, c2.y, c2.z);

            Matrix4 mat = new Matrix4();

            mat.values[ 0] = c0.x / scale.x;        mat.values[ 4] = c1.x / scale.y;        mat.values[ 8] = c2.x / scale.z;    mat.values[12] = 0;
            mat.values[ 1] = c0.y / scale.x;        mat.values[ 5] = c1.y / scale.y;        mat.values[ 9] = c2.y / scale.z;    mat.values[13] = 0;
            mat.values[ 2] = c0.z / scale.x;        mat.values[ 6] = c1.z / scale.y;        mat.values[10] = c2.z / scale.z;    mat.values[14] = 0;
            mat.values[ 3] = 0;                     mat.values[ 7] = 0;                     mat.values[11] = 0;                 mat.values[15] = 1;
            rotationAxisAndAngle = mat.toAxisAngle();
            System.out.println("<Transform translation=\"" + translation.x + " " + translation.y + " " + translation.z + "\">");
            System.out.println("<Transform rotation=\"" + rotationAxisAndAngle.x + " " + rotationAxisAndAngle.y + " " + rotationAxisAndAngle.z + " " + rotationAxisAndAngle.w + "\">");
            System.out.println("<Transform scale=\"" + scale.x + " " + scale.y + " " + scale.z + "\">");
        }

But the axis angle and the scale factor which it retrieves are incorrect.
What's wrong with it?

mrcointreau
  • 342
  • 5
  • 16
  • I do not know the code of Matrix4 that you are using, but I would expect that you want to calculate the axis and angle of only the upper left 3x3 block of the matrix `mat`. – Bernhard Bodenstorfer Aug 07 '17 at 18:57

0 Answers0