用于在视口和变换后的矩形之间变换坐标的矩阵
Matrix to transform coordinates between viewport and transformed rectangle
我正在尝试编写一个矩阵,在屏幕上已转换矩形的局部坐标和视口坐标之间进行转换。
如下图所示:
- 红色局部(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)
我很确定这与我的操作顺序有关,但我尝试了很多东西,但无法弄清楚。
我设法通过为视口使用绝对像素坐标而不是相对 [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;
}
}
我正在尝试编写一个矩阵,在屏幕上已转换矩形的局部坐标和视口坐标之间进行转换。
如下图所示:
- 红色局部(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)
我很确定这与我的操作顺序有关,但我尝试了很多东西,但无法弄清楚。
我设法通过为视口使用绝对像素坐标而不是相对 [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;
}
}