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));
Be Sociable, Share!

4 comments

    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;

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>