【问题标题】:Decompose 2D Transformation Matrix分解二维变换矩阵
【发布时间】:2017-12-22 21:08:29
【问题描述】:

所以,我有一个 Direct2D Matrix3x2F,用于存储几何转换。我希望这些转换是用户可编辑的,并且我不希望用户必须直接编辑矩阵。是否可以将 3x2 矩阵分解为缩放、旋转、倾斜和平移?

【问题讨论】:

    标签: c# math direct2d


    【解决方案1】:

    这是我为 Direct2D 转换矩阵找到的解决方案:

    • 缩放 x = sqrt(M11 * M11 + M12 * M12)

    • 缩放 y = sqrt(M21 * M21 + M22 * M22) * cos(shear)

    • 旋转 = atan2(M12, M11)

    • 剪切 (y) = atan2(M22, M21) - PI/2 - rotation

    • 翻译 x = M31

    • 翻译 y = M32

    如果您按照scale(x, y) * skew(0, shear) * rotate(angle) * translate(x, y) 的顺序将这些值相乘,您将得到一个执行等效变换的矩阵。

    【讨论】:

      【解决方案2】:
      1. 分解

        是的,你可以(至少部分)。 3x2 变换矩阵表示没有投影的 2D 同质 3x3 变换矩阵。这样的变换矩阵要么是 OpenGL 风格:

        | Xx Yx Ox |
        | Xy Yy Oy |
        

        DirectX风格:

        | Xx Xy |
        | Yx Yy |
        | Ox Oy |
        

        当您标记 Direct2D 并使用 3x2 矩阵时,第二个就是您得到的。有3向量:


        X=(Xx,Xy) X 轴矢量
        Y=(Yx,Yy)Y轴矢量
        O=(Ox,Oy)坐标系原点。

        现在让我们假设不存在偏斜并且矩阵是正交...

      2. 缩放

        非常简单,只需获取轴基向量长度即可。

        scalex = sqrt( Xx^2 + Xy^2 );
        scaley = sqrt( Yx^2 + Yy^2 );
        

        比例系数是>1,矩阵放大,如果<1缩小。

      3. 轮换

        你可以使用:

        rotation_ang=atan2(Xy,Yx);
        
      4. 翻译

        偏移量是O,所以如果它不为零,则表示存在翻译。

      5. 倾斜

        2D 中,倾斜不会使事情过于复杂,上面的要点仍然适用(3D 不是这种情况)。倾斜角是轴之间的角度减去90 度,所以:

        skew_angle = acos((X.Y)/(|X|.|Y|)) - 0.5*PI;
        skew_angle = acos((Xx*Yx + Xy*Yy)/sqrt(( Xx^2 + Xy^2 )*( Yx^2 + Yy^2 ))) - 0.5*PI;
        

      还要注意,如果您的变换矩阵不代表您的坐标系而是它的逆矩阵,那么您需要在应用它之前反转您的矩阵...

      所以计算第一个逆:

      | Xx Xy 0 |
      | Yx Yy 0 |
      | Ox Oy 1 |
      

      并将上述内容应用于结果。

      有关此主题的更多信息,请参阅:

      尤其是列主要顺序和行主要顺序之间的区别(OpenGLDirectX 表示法)

      【讨论】:

        【解决方案3】:

        将主要转换存储在具有可编辑属性的类中

           scaling
           rotation
           skewing
           translation
        

        然后从中构建最终的变换矩阵。这样会更容易。但是,如果您必须有分解矩阵的算法。它们并不像您想象的那么简单。

        System.Numerics 有分解 3D 变换矩阵的方法

        https://github.com/dotnet/corefx/blob/master/src/System.Numerics.Vectors/src/System/Numerics/Matrix4x4.cs#L1497

        【讨论】:

        • 关于二维矩阵的问题
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-06-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多