在视口和变换后的矩形之间变换坐标的矩阵

Posted

技术标签:

【中文标题】在视口和变换后的矩形之间变换坐标的矩阵【英文标题】:Matrix to transform coordinates between viewport and transformed rectangle 【发布时间】:2022-01-17 04:47:38 【问题描述】:

我正在尝试编写一个矩阵,在屏幕上转换的矩形的局部坐标和视口坐标之间进行转换。

如下图所示:

红色的局部 (L) 坐标代表矩形,从 (0, 0) 到 (1, 1) 橙色的全局 (G) 坐标代表视口,从 (0, 0) 到 (1, 1) 矩形以其 (0.5, 0.5) 坐标为中心,并围绕该枢轴旋转 theta(橙色) 我正在尝试编写一个矩阵,将绿色局部坐标转换为洋红色全局坐标

到目前为止,我有以下代码,它适用于平移和缩放,并且似乎朝正确的方向旋转。

但在应用旋转时似乎存在某种形式的倾斜

public Matrix4x4 LocalToViewportMatrix

    get
    
        Vector2 translation = viewportPosition;
        float rotation = this.rotation;
        Vector2 scale = viewportSize;
        Vector2 centering = -(new Vector2(0.5f, 0.5f));
        
        Matrix4x4 T = Matrix4x4.Translate(translation.WithZ(0));
        Matrix4x4 R = Matrix4x4.Rotate(Quaternion.Euler(0, 0, rotation));
        Matrix4x4 S = Matrix4x4.Scale(scale.WithZ(1));
        Matrix4x4 t = Matrix4x4.Translate(centering.WithZ(0));

        return T * R * S * t;
    

viewportPosition 映射到图表上的蓝色 G(x, y) 矩形中心 rotation 映射到图表上的橙色 theta 角 viewportSize 映射到 未旋转 矩形相对于视口的相对大小;基本上如果你拿了length(red axes) / length(blue axes)

我很确定这与我的操作顺序有关,但我尝试了很多方法并无法弄清楚。

【问题讨论】:

这听起来很像Camera.worldToCameraMatrix 【参考方案1】:

我设法通过使用视口的绝对像素坐标而不是相对 [0, 1] 范围来解决我的问题。我不确定如何解释它,但我认为坐标系在两个轴上的长度不同这一事实导致了倾斜。

public Matrix4x4 LocalToScreenMatrix

    get
    
        var ScreenSize = new Vector2(Screen.width, Screen.height);
        var screenPosition = viewportPosition * ScreenSize;
        var screenSize = viewportSize * ScreenSize;

        var translation = screenPosition;
        var rotation = this.rotation;
        var scale = screenSize;
        var centering = -new Vector2(0.5f, 0.5f);

        var T = Matrix4x4.Translate(translation.WithZ(0));
        var R = Matrix4x4.Rotate(Quaternion.Euler(0, 0, rotation));
        var S = Matrix4x4.Scale(scale.WithZ(1));
        var t = Matrix4x4.Translate(centering.WithZ(0));

        return T * R * S * t;
    

【讨论】:

以上是关于在视口和变换后的矩形之间变换坐标的矩阵的主要内容,如果未能解决你的问题,请参考以下文章

CSS3 matrix3d矩阵变换和动画变换

Unity面试题汇总

图像处理-图像的旋转及变换

OpenGl从零开始之坐标变换

OpenGLES 透视变换与屏幕UV坐标

Qt Coordinate System