Calculate the REAL scale factor and the angle of rotation from an Android Matrix

After performing transformations such as rotation of a bitmap about an arbitrary point, the scale is lost. Of course, this makes sense because the bitmap is rotated inside the same bounds.

To get the real scale now, along with the most reliable degree of rotation, I had to follow this method. Hope it saves the rest of you a night or two.

float[] v = new float[9];
matrix.getValues(v);
// translation is simple
float tx = v[Matrix.MTRANS_X];
float ty = v[Matrix.MTRANS_Y];

// calculate real scale
float scalex = values[Matrix.MSCALE_X];
float skewy = values[Matrix.MSKEW_Y];
float rScale = (float) Math.sqrt(scalex * scalex + skewy * skewy);

// calculate the degree of rotation
float rAngle = Math.round(Math.atan2(v[Matrix.MSKEW_X], v[Matrix.MSCALE_X]) * (180 / Math.PI));

Comments

4 responses to “Calculate the REAL scale factor and the angle of rotation from an Android Matrix”

  1. where to use rScale

    1. if (lastEvent != null && event.getPointerCount() == 3) {
      // newRot = rotation(event);
      // float r = newRot – d;
      float[] v1 = new float[9];
      matrix.getValues(v1);
      float tx = v1[Matrix.MTRANS_X];
      float ty = v1[Matrix.MTRANS_Y];
      // calculate real scale
      float scalex = v1[Matrix.MSCALE_X];
      float skewy = v1[Matrix.MSKEW_Y];
      float rScale = (float) Math.sqrt(scalex * scalex + skewy *skewy);

      // degree of rotation
      float rAngle = Math.round(Math.atan2(v1[Matrix.MSKEW_X], v1[Matrix.MSKEW_X]) * (180 / Math.PI));

      // float tx = values[2];
      // float ty = values[3];
      // float sx = values[0];
      // float xc = (view.getWidth() / 2) * sx;
      // float yc = (view.getHeight() / 2) * sx;
      matrix.postRotate(rAngle, tx + scalex, ty + skewy);
      }
      }
      break;

  2. Thank you!

  3. Thank you for this snippet. Saved me a lot of hassle trying to reset the rotation of a matrix in my application.