Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从变换矩阵求角度_Java_Math - Fatal编程技术网

Java 从变换矩阵求角度

Java 从变换矩阵求角度,java,math,Java,Math,我有一个像这样的值的变换矩阵 变换:分别为xx、xy、yx、yy、tx和ty 如何从上述给定值集合中找到角度。参考维基百科关于变换矩阵的页面: tx和ty是翻译。其余元素组成旋转矩阵: xx xy yx yy 请注意,这相当于 cos(θ) sin(θ) -sin(θ) cos(θ) 其中,θ为顺时针旋转角度。从中可以得到xx=yy=cos(θ)和xy=-yx=sin(θ)。角度的计算公式为数学atan2(xy,xx)。这将给您一个介于-π和π之间的结果Math.acos(xx),Math

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

变换:分别为xx、xy、yx、yy、tx和ty


如何从上述给定值集合中找到角度。

参考维基百科关于变换矩阵的页面:

tx
ty
是翻译。其余元素组成旋转矩阵:

xx xy
yx yy
请注意,这相当于

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

其中,
θ
为顺时针旋转角度。从中可以得到
xx=yy=cos(θ)
xy=-yx=sin(θ)
。角度的计算公式为
数学atan2(xy,xx)
。这将给您一个介于
π
之间的结果
Math.acos(xx)
Math.acos(yy)
Math.asin(xy)
Math.asin(-yx)
-Math.asin(yx)
这6个数字描述了一种仿射变换,通常包括(非均匀)缩放、旋转和平移。翻译用
(tx,ty)
表示。剩下的4个数字必须分解为缩放和旋转。最简单的方法是:将矩阵分解为
M=UDV
,其中
M
是原始矩阵

xx xy
yx yy

U和V是正交旋转矩阵,D是对角矩阵。这将仿射变换表示为三个步骤:旋转
V
,然后缩放
D
,以及旋转
U
D
的两个条目是x和y的两个比例系数。从
U
V
可以获得旋转角度,如Mad物理学家所述。总旋转是两者的总和。

如果只是关于旋转,可以使用给定矩阵变换向量(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;
    }


}
导入java.awt.Point;
导入java.awt.geom.AffineTransform;
导入java.awt.geom.Point2D;
导入java.util.Random;
公营班级轮换
{
公共静态void main(字符串[]args)
{

对于(int i=0;i如果选择使用具有4个自由度(缩放、旋转和平移)的仿射变换,则不必分解旋转矩阵。 对于提取平移和旋转,有一种直接的解决方案

下面是一个使用opencv的python实现

    # Note: This function calculate only 4 degrees of freedom !!! scaling, rotation and translation
    h, mask = cv.estimateAffinePartial2D(pointsRef, pointsCur, method=cv.RANSAC, ransacReprojThreshold=3, confidence=0.9)

    # Estimate the rotation angle from the matrix [s]
    # Extract traslation
    dx = h[0, 2]
    dy = h[1, 2]

    # Extract rotation angle
    da = np.arctan2(h[1, 0], h[0, 0])
    print(np.rad2deg(da))

    # Store transformation
    transforms = [dx, dy, da]

可能是重复的。我个人会从这个答案中推荐这种方法:谢谢你,Marco,你有类似的java代码吗?在中添加了一些代码,如果你只有这六个参数,这意味着它们被适当地缩放了,否则你会丢失矩阵最后一行的信息。谢谢@Marco13,这正是我要找的。你知道是否也可以从给定的值中找到比例和转换信息。转换是通过用给定的矩阵转换点(0,0)的结果给出的。可以根据上述代码中
pp0
pp1
之间的距离来计算比例(如果缩放不均匀,则其x坐标和y坐标的差异)