从变换矩阵中寻找角度

时间:2014-02-04 19:44:49

标签: java math

我有一个像这样的值的变换矩阵。

分别转换:xx,xy,yx,yy,tx和ty。

如何从上面的给定值集中找到角度。

4 个答案:

答案 0 :(得分:2)

如果仅关于旋转,可以使用给定矩阵变换矢量(1,0),并计算结果矢量和x轴之间的角度,如原始问题的注释中所述< / p>

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;
    }


}

答案 1 :(得分:1)

参考关于转换矩阵的维基百科页面:http://en.wikipedia.org/wiki/Transformation_matrix#Affine_transformations

txty是翻译。其余元素构成一个旋转矩阵:

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之间的角度。

答案 2 :(得分:0)

这6个数字描述了一个仿射变换,它通常由(非均匀)缩放,旋转和平移组成。翻译由(tx, ty)表示。这留下剩余的4个数字,必须将其分解为缩放和旋转。最简单的方法是Singular value decomposition:在这里,您将矩阵分解为M=UDV,其中M是您的原始矩阵

xx xy
yx yy

U和V是正交旋转矩阵,D是对角矩阵。这表示您的仿射变换分为三个步骤:轮换V,然后是缩放D和轮换UD的两个条目是x和y的两个缩放系数。从UV,您可以获得旋转角度,如Mad Physicist所述。总旋转是两者的总和。

答案 3 :(得分:0)

如果您选择使用具有4个自由度的仿射变换(缩放,旋转和平移),则不必分解旋转矩阵。 提取平移和旋转有直接解决方案

这是带有opencv的python实现

map<string, long long int>