2014-02-04 2 views
1

У меня есть матрица преобразования со значениями, подобными этому.Поиск угла из матрицы преобразования

Преобразование: xx, xy, yx, yy, tx и ty соответственно.

Как найти угол из приведенного выше набора значений.

+0

Возможно дубликат http://stackoverflow.com/questions/4361242/extract-rotation-scale-values-from-2d-transformation-matrix. Я лично рекомендовал бы подход из этого ответа: http://stackoverflow.com/a/9625358/ – Marco13

+0

спасибо Марко, у вас есть аналогичный код Java для этого –

+0

Добавлен код в http://stackoverflow.com/ a/21565237/ – Marco13

ответ

2

Если речь идет только о вращении, можно преобразовать вектор (1,0) с использованием заданной матрицы и вычислить угол между результирующим вектором и осью х, как уже упоминалось в комментарии к исходному вопросу

import java.awt.Point; 
import java.awt.geom.AffineTransform; 
import java.awt.geom.Point2D; 
import java.util.Random; 


public class ExtractRotation 
{ 
    public static void main(String[] args) 
    { 
     for (int i=0; i<=180; i++) 
     { 
      double angleRad = Math.toRadians(i); 
      AffineTransform at = createRandomTransform(angleRad); 
      double extractedAngleRad = extractAngle(at); 
      System.out.println(
       "In: "+Math.toDegrees(angleRad)+ " " + 
       "Out "+Math.toDegrees(extractedAngleRad)); 
     } 
    } 

    private static double extractAngle(double m[]) 
    { 
     return extractAngle(new AffineTransform(m)); 
    } 
    private static double extractAngle(AffineTransform at) 
    { 
     Point2D p0 = new Point(); 
     Point2D p1 = new Point(1,0); 
     Point2D pp0 = at.transform(p0, null); 
     Point2D pp1 = at.transform(p1, null); 
     double dx = pp1.getX() - pp0.getX(); 
     double dy = pp1.getY() - pp0.getY(); 
     double angle = Math.atan2(dy, dx); 
     return angle; 
    } 

    private static Random random = new Random(0); 
    private static AffineTransform createRandomTransform(double angleRad) 
    { 
     AffineTransform at = new AffineTransform(); 
     double scale = 1.0; 
     at.translate(randomDouble(), randomDouble()); 
     scale = Math.abs(randomDouble()); 
     at.scale(scale, scale); 
     at.rotate(angleRad); 
     at.translate(randomDouble(), randomDouble()); 
     scale = Math.abs(randomDouble()); 
     at.scale(scale, scale); 
     return at; 
    } 

    private static double randomDouble() 
    { 
     return -5.0 + random.nextDouble() * 10; 
    } 


} 
+0

Спасибо @ Marco13, это именно то, что я искал. Знаете ли вы, что также можно найти ** масштаб ** и ** перевести ** информацию из заданных значений. –

+0

Перевод задается результатом преобразования точки (0,0) с заданной матрицей. Масштабирование может быть вычислено с расстояния между 'pp0' и' pp1' в вышеуказанном коде (или разностью их x- и y-координат, если масштабирование неоднородно) – Marco13

1

Со ссылкой на страницу Википедии о матрицах трансформации: http://en.wikipedia.org/wiki/Transformation_matrix#Affine_transformations.

tx и ty - это переводы. Остальные элементы составляют матрицу вращения:

xx xy 
yx yy 

Заметим, что это эквивалентно

cos(θ) sin(θ) 
-sin(θ) cos(θ) 

где θ является угол поворота по часовой стрелке. Из этого вы получите это xx = yy = cos(θ) и xy = -yx = sin(θ). Угол может быть рассчитан как Math.atan2(xy, xx). Это даст вам результат, который находится между и π. Math.acos(xx), Math.acos(yy), Math.asin(xy), Math.asin(-yx) и -Math.asin(yx) все работы для углов между нулями, чем π/2.

+0

Если у вас есть только эти шесть параметров, подразумевается, что они правильно масштабируются, в противном случае вам не хватает информации из последней строки матрицы. –

0

Эти 6 чисел описывают аффинное преобразование, которое в общем состоит (неравномерного) масштабирования, вращения и перевода. Перевод представлен (tx, ty). Это оставляет оставшиеся 4 числа, которые необходимо разложить на масштабирование и вращение. Самый простой способ сделать это было бы Singular value decomposition: Здесь вы разлагать матрицу, как M=UDV, где M ваша исходная матрица

xx xy 
yx yy 

U и V являются ортогональными матрицами вращения, и D является диагональной матрицей. Это представляет собой ваше аффинное преобразование как три шага, поворот V, за которым следует масштабирование D и вращение U. Две записи из D являются двумя коэффициентами масштабирования для x и y. С U и V вы можете получить углы поворота, как описано Mad Physicist. Общее вращение - это сумма обоих.

Смежные вопросы