Аффинное преобразование можно представить в виде последовательностей переводов, вращений, отражений, масштабов и сдвигов. Способ их вычисления называется матричная декомпозиция .
Для пакетов программного обеспечения существует множество опций, например, JAMA package или Apache Commons Math .
Разложение по сингулярным числам (SVD) дает вам разложение на вращение с последующим масштабированием и последующим вращением.
Вот пример, который использует JAMA для вычисления SVD сдвига и извлечения из него углов поворота и коэффициентов масштабирования:
import Jama.*;
public class Demo {
public static void main(String[] args) {
double[][] vals = {{1, 1}, {0, 2}};
Matrix a = new Matrix(vals);
SingularValueDecomposition svd = a.svd();
Matrix u = svd.getU();
Matrix v = svd.getV();
double[] s = svd.getSingularValues();
System.out.printf("rotate=%f scaleX=%f scaleY=%f rotate=%f\n",
Math.toDegrees(Math.atan2(u.get(0, 1), u.get(0, 0))),
s[0], s[1],
Math.toDegrees(Math.atan2(v.get(0, 1), v.get(0, 0))));
}
}
Вывод говорит вам, что это вращение на 76 градусов Затем следуют шкала X и шкала Y, а затем поворот на 58 градусов:
rotate=-58.282526 scaleX=2.288246 scaleY=0.874032 rotate=-76.717474
Осторожно: если ваше преобразование включает в себя переворачивание изображения, этот код не будет работать. Процедура SVD в JAMA объединит зеркалирование с одним из вращений. Поскольку у вас есть только матрицы 2x2, вы можете рассмотреть возможность написания своей собственной специализированной реализации SVD.
С помощью других разложений матриц вы можете получить другие представления, например, shear-scale-shear (LU decomp) или вращение масштабные ножницы (QR decomp)