1

我有两个正方形,S1 = (x1,y1,x2,y2) 和 S2 = (a1,b1,a2,b2)

我正在寻找 A * S1 = S2 的转换矩阵

据我所知,A 是一个 3x3 仿射矩阵,所以我有 9 个未知值。

如何计算这些值?

谢谢,最好的,维克多

4

5 回答 5

6

这里实际上只有四个未知值。旋转角度、比例因子和 x 和 y 平移。在您的三乘三矩阵中,最下面一行总是0,0,1将您减少到六个未知数。右手栏将Tx,Ty,1是您的翻译(以及我们已经知道的 1)。

剩下的两乘二“矩阵”将是您的旋转和缩放。这将(在我脑海中)类似于:

ACos(B), -Asin(B)
ASin(B),  aCos(B)

所以总的来说:

ACos(B), -Asin(B), Tx
ASin(B),  ACos(B), Ty
0      ,  0      , 1

你用每个坐标末尾的 1 来扩展你的坐标矩阵,得到 2x3 矩阵,然后它们相乘得到你需要求解四个变量的四个方程。这留给读者作为练习。

于 2010-07-09T12:56:11.683 回答
2

变换矩阵是缩放矩阵Ss、转移矩阵St和旋转矩阵Sr的因子。

假设旧点是 Po 是 (Xo,Yo) 并且向量将表示为 (Xo Yo 1)' 与新点 Pn 相同 那么 Pnv =Ss St SrPov 其中 Sx 是

Sx  0    0
0   Sy   0
0   0    1

圣是

1   0   Tx
0   1   Ty
0   0   1

Cos(th)    -Sin(th)    0
Sin(th)     Cos(th)    0
0           0          1

现在回到你的问题。如果两个点代表一个矩形,我们可以找到两个矩阵的参数,第三个将是一个单位矩阵。

Rect1 表示为左上点 P11 和右下点 P12 Rect2 表示为左上点 P21 和右下点 P22

S=Ss*St

Sx  0  Tx
0   Sy Ty
0   0  1

现在你有 4 个缺失的参数和 4 组方程

P21=S*P11
P22=S*P12

X[P21] =Sx*X[P11]+Tx
Y[P21] =Sy*Y[P11]+Ty
X[P22] =Sx*X[P12]+Tx
Y[P22] =Sy*Y[P12]+Ty

解决它,你就会得到答案。

如果你有过渡和旋转,那么 S=Sr*St。

Cos(th)    -Sin(th)    Tx
Sin(th)     Cos(th)    Ty
0           0          1

现在你有 3 个缺失的参数和 4 组方程

P21=S*P11
P22=S*P12

X[P21] =Cos(th)*X[P11]-Sin(th)*Y[P11]+Tx
Y[P21] =Sin(th)*X[P11]+Cos(th)*Y[P11]+Ty
X[P22] =Cos(th)*X[P11]-Sin(th)*Y[P12]+Tx
Y[P22] =Sin(th)*X[P11]+Cos(th)*Y[P12]+Ty

将 Cos(th) 替换为 A 并将 Sin(th) 替换为 B 并求解方程。

X[P21] =A*X[P11]-B*Y[P11]+Tx
Y[P21] =B*X[P11]+A*Y[P11]+Ty
X[P22] =A*X[P11]-B*Y[P12]+Tx
Y[P22] =B*X[P11]+A*Y[P12]+Ty

检查它是否正确A^2+B^2 =? 1如果是真的那么th = aCos(A)

解决方案的最后一部分,如果你将拥有所有三个矩阵,那么 S=Sr St Ss 是

 Sx*sin(th) -Sx*cos(th)  Tx
 Sy*cos(th)  Sy*sin(th)  Ty
          0           0   1

现在我们有 5 个缺失变量,我们需要 6 个不同的方程组来解决它。这意味着每个矩形的平均 3 个点。

于 2010-07-09T18:39:54.170 回答
0

如果您只是想转换 2D 对象,则不应使用 3x3 矩阵。您正在寻找的是解决 A*S1=S2 的 2x2 矩阵。这可以通过许多不同的方式来完成;在 MATLAB 中,你会做一个S2/S1右矩阵除法),通常这会执行某种高斯消除

于 2010-07-09T10:33:36.753 回答
0

如何计算这些值?

当应用于 2d/3d 变换时,矩阵可以表示为一个坐标系,除非我们在谈论投影。

矩阵行(或列,取决于符号)形成新坐标系的轴,如果每个对象顶点都乘以矩阵,则将放置对象。最后一行(或列,取决于符号)指向新坐标系的中心。

标准 OpenGL/DirectX 变换矩阵(不是投影矩阵):

class Matrix{//C++ code
public:
    union{
        float f[16];
        float m[4][4];
    };
};

可以表示为4个向量vx(新坐标系的x轴)、vy(新坐标系的y轴)、vz(新坐标系的z轴)和vp(新坐标系的中心)的组合. 像这样:

vx.x vx.y vx.z 0
vy.x vy.y vy.z 0
vz.x vz.y vz.z 0
vp.x vp.y vp.z 1

所有“计算旋转矩阵”、“计算比例矩阵”等都归结为这个想法。

因此,对于 2d 矩阵,您将拥有由 3 个向量组成的 3x3 矩阵 - vx、vy、vp,因为 2d 中没有 z 向量。IE:

vx.x vx.y 0
vy.x vy.y 0
vp.x vp.y 1

要找到将四边形 A 转换为四边形 B 的变换,您需要找到两个变换:

  1. 将四边形 A 移动到原点(即零点)的变换,并将其转换为固定大小的四边形。比如说,四边形(矩形),它的一个顶点 x = 0, y = 0,其顶点位于 (0, 1), (1, 0), (1, 1)。
  2. 将固定大小的四边形转换为四边形 B 的变换。

如果四边形的相对边缘不平行,则不能这样做。即平行四边形很好,但随机的 4 边多边形不是。

四边形可以由基点 (vp) 表示,该基点可以是四边形的任何顶点和定义四边形大小的两个向量(边的方向乘以边的长度)。即“上”向量和“侧”向量。这使它成为一个矩阵:

side.x side.y 0
up.x   up.y   0
vp.x   vp.y   1

因此,将四边形 (vp.x = 0, vp.y = 0, side.x = 1, side.y = 0, up.x = 0, up.y = 1) 乘以该矩阵会将原始四边形变为你的四边形。这意味着,为了将四边形 A 转换为四边形 B,您需要执行以下操作:

1)制作一个矩阵,将“base 1unit quad”转换为quad A。我们称之为matA。
2)制作一个矩阵,将“base 1 unit quad”转换为quad B。我们称之为matB。
3)反转matA并将结果存储到invMatA中。
4)结果矩阵为invMatA * matB。

完毕。如果将四边形 A 与结果矩阵相乘,您将得到四边形 B。如果四边形的宽度或高度为零,则这将不起作用,如果四边形不是平行四边形,则它将不起作用。

这很难理解,但我不能让它更简单。

于 2010-07-11T18:06:14.973 回答
-1

你是什​​么意思S1 = (x1,y1,x2,y2)

它们代表正方形的左上角和右下角吗?

此外,您能否保证正方形之间只有旋转,或者您是否需要允许缩放、倾斜和平移的完整仿射变换?

还是您还需要透视变换?

仅当它是透视变换时,您才需要像您在帖子中提到的那样具有 8 个自由度的 3x3 矩阵。

于 2010-07-09T12:26:43.043 回答