我有两个正方形,S1 = (x1,y1,x2,y2) 和 S2 = (a1,b1,a2,b2)
我正在寻找 A * S1 = S2 的转换矩阵
据我所知,A 是一个 3x3 仿射矩阵,所以我有 9 个未知值。
如何计算这些值?
谢谢,最好的,维克多
我有两个正方形,S1 = (x1,y1,x2,y2) 和 S2 = (a1,b1,a2,b2)
我正在寻找 A * S1 = S2 的转换矩阵
据我所知,A 是一个 3x3 仿射矩阵,所以我有 9 个未知值。
如何计算这些值?
谢谢,最好的,维克多
这里实际上只有四个未知值。旋转角度、比例因子和 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 矩阵,然后它们相乘得到你需要求解四个变量的四个方程。这留给读者作为练习。
变换矩阵是缩放矩阵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 个点。
如何计算这些值?
当应用于 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 的变换,您需要找到两个变换:
如果四边形的相对边缘不平行,则不能这样做。即平行四边形很好,但随机的 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。如果四边形的宽度或高度为零,则这将不起作用,如果四边形不是平行四边形,则它将不起作用。
这很难理解,但我不能让它更简单。
你是什么意思S1 = (x1,y1,x2,y2)
?
它们代表正方形的左上角和右下角吗?
此外,您能否保证正方形之间只有旋转,或者您是否需要允许缩放、倾斜和平移的完整仿射变换?
还是您还需要透视变换?
仅当它是透视变换时,您才需要像您在帖子中提到的那样具有 8 个自由度的 3x3 矩阵。