从变换矩阵中寻找角度
我有一个像这样的值的变换矩阵。
变换:分别为xx,xy,yx,yy,tx和ty。
如何从上面的给定值集中找到角度。
如果仅关于旋转,可以使用给定矩阵变换矢量(1,0),并计算结果矢量和x轴之间的角度,如原始问题的注释中所述。
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; } }
参考关于转换矩阵的维基百科页面: 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)
都适用于0到π/2
之间的角度。
这6个数字描述仿射变换,其通常由(非均匀)缩放,旋转和平移组成。 翻译由(tx, ty)
。 这留下了剩余的4个数字,必须将其分解为缩放和旋转。 最简单的方法是奇异值分解 :在这里你将矩阵分解为M=UDV
,其中M
是你的原始矩阵
xx xy yx yy
U和V是正交旋转矩阵,D是对角矩阵。 这表示您的仿射变换分为三个步骤,即旋转V
,然后是缩放D
和旋转U
D
的两个条目是x和y的两个缩放系数。 从U
和V
您可以获得旋转角度,如Mad Physicist所述。 总旋转是两者的总和。