#android #opengl-es #opengl-es-2.0
#Android #opengl-es #opengl-es-2.0
Вопрос:
Я пытаюсь масштабировать точку, используя подход:
- переведите в точку, которую я хочу масштабировать (пинч-зум)
- масштабирование
- перевести обратно
Это выглядит как:
@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);
Но когда я создаю результирующую матрицу MVP, например:
Matrix.multiplyMM(MVPmatrix, 0,
projectionMatrix, 0,
modelMatrix, 0);
Я получаю неправильное масштабирование, так что оно масштабируется, но оно неправильно масштабируется вокруг точки..
Не могли бы вы посоветовать, что может быть причиной и как правильно масштабировать вокруг точки?
Ответ №1:
Насколько я могу судить, методы в классе утилиты Android Matrix
умножают вновь указанные преобразования справа. Я не вижу, чтобы это было указано в документации, но исходный код ( http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/opengl/Matrix.java ) явно предполагает, что это работает таким образом.
Это означает, что когда вы объединяете матрицу преобразования из последовательности подтрансформаций, последний вызываемый вами метод определяет подтрансформацию, которая применяется к вашим точкам первой. Другими словами, вы указываете матрицы в порядке, обратном порядку их применения к вашим точкам.
Для поворота вокруг вашей точки (focusX, focusY)
сначала нужно применить перевод на (-focusX, -focusY, 0.0f)
к вашим точкам, затем поворот, затем перевод на (focusX, focusY, 0.0f)
. Поскольку последовательность вызовов обратная этой, она должна быть:
Matrix.translateM(modelMatrix, 0, focusX, focusY, 0.0f);
Matrix.scaleM(modelMatrix, 0, scaleFactor, scaleFactor, scaleFactor);
Matrix.translateM(modelMatrix, 0, -focusX, -focusY, 0.0f);
Я также изменил последний аргумент scaleM()
здесь. Поскольку у вас был 0
масштабный коэффициент в направлении z, вы бы сгладили всю геометрию в плоскости x-y.