У меня есть матрица преобразования со значениями, подобными этому.Поиск угла из матрицы преобразования
Преобразование: xx, xy, yx, yy, tx и ty соответственно.
Как найти угол из приведенного выше набора значений.
У меня есть матрица преобразования со значениями, подобными этому.Поиск угла из матрицы преобразования
Преобразование: xx, xy, yx, yy, tx и ty соответственно.
Как найти угол из приведенного выше набора значений.
Если речь идет только о вращении, можно преобразовать вектор (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;
}
}
Спасибо @ Marco13, это именно то, что я искал. Знаете ли вы, что также можно найти ** масштаб ** и ** перевести ** информацию из заданных значений. –
Перевод задается результатом преобразования точки (0,0) с заданной матрицей. Масштабирование может быть вычислено с расстояния между 'pp0' и' pp1' в вышеуказанном коде (или разностью их x- и y-координат, если масштабирование неоднородно) – Marco13
Со ссылкой на страницу Википедии о матрицах трансформации: 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
.
Если у вас есть только эти шесть параметров, подразумевается, что они правильно масштабируются, в противном случае вам не хватает информации из последней строки матрицы. –
Эти 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. Общее вращение - это сумма обоих.
Возможно дубликат http://stackoverflow.com/questions/4361242/extract-rotation-scale-values-from-2d-transformation-matrix. Я лично рекомендовал бы подход из этого ответа: http://stackoverflow.com/a/9625358/ – Marco13
спасибо Марко, у вас есть аналогичный код Java для этого –
Добавлен код в http://stackoverflow.com/ a/21565237/ – Marco13