Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scaling around point (pinch zoom) with Android and OpenGL ES 2.0

I'm trying to scale around the point using approach:

  • translate to the point I want to scale around (pinch zoom)
  • scale
  • translate back

It looks like:

@Override
public boolean onScale(ScaleGestureDetector detector) {

    float scaleFactor = detector.getScaleFactor();

    float focusX = detector.getFocusX();
    float focusY = detector.getFocusY();

    Matrix.translateM(modelMatrix, 0, -focusX, -focusY, 0);
    Matrix.scaleM(modelMatrix, 0, scaleFactor, scaleFactor, 0);
    Matrix.translateM(modelMatrix, 0, focusX, focusY, 0);

But when I create result MVP matrix like:

Matrix.multiplyMM(MVPmatrix, 0,
    projectionMatrix, 0,
    modelMatrix, 0);

I get incorrect scaling so that it scales but it doesn't scale around the point correctly..

Could you advise what could be the reason and how to scale around the point correctly?

like image 387
XZen Avatar asked Dec 11 '25 10:12

XZen


1 Answers

As far as I can tell, the methods in the Android Matrix utility class multiply the newly specified transformations from the right. I don't see it specified in the documentation, but the source code (http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/opengl/Matrix.java) clearly suggests that it works this way.

This means that when you combine a transformation matrix from a sequence of sub-transformations, the last method you invoke specifies the sub-transformation that is applied to your points first. In other words, you specify the matrices in the reverse of the order that they are applied to your points.

For the rotation around your point (focusX, focusY), you first want to apply the translation by (-focusX, -focusY, 0.0f) to your points, then the rotation, then the translation by (focusX, focusY, 0.0f). Since the call sequence is the reverse of this, it should be:

Matrix.translateM(modelMatrix, 0, focusX, focusY, 0.0f);
Matrix.scaleM(modelMatrix, 0, scaleFactor, scaleFactor, scaleFactor);
Matrix.translateM(modelMatrix, 0, -focusX, -focusY, 0.0f);

I also changed the last argument of scaleM() here. Since you had 0 for the scale factor in z-direction, you would be flattening the entire geometry into the x-y plane.

like image 165
Reto Koradi Avatar answered Dec 13 '25 23:12

Reto Koradi