我正试图从闪存影片剪辑中的转换矩阵中获取偏斜值。转换矩阵由
表示a b tx
c d ty
0 0 1
我没有关于执行什么类型的转换以及哪个转换的信息。我知道在flash中你只能旋转或歪曲一个影片剪辑(如果我错了,请纠正我)。我可以从影片剪辑的scaleX和scaleY属性中获取缩放值。我认为翻译并不重要,我可以将tx和ty等同为零。
所以我的问题有2个部分。如何确定是否应用了倾斜或旋转,以及如何获取相应的值?
答案 0 :(得分:2)
2D旋转矩阵
cos(theta) -sin(theta)
sin(theta) cos(theta)
所以如果你没有应用缩放或剪切,
a = d
and
c = -b
and the angle of rotation is
theta = asin(c) = acos(a)
如果你已经应用了缩放并且可以恢复缩放因子sx和sy,只需将第一行除以sx,将第二行除以原始变换矩阵中的sy,然后如上所述恢复旋转角度。
如果你在那里的任何地方都有剪切(歪斜),我和之前的评论者一样,除非在非常有限的情况下(例如一次只有一个已知方向的剪切)一个已知的命令)。
答案 1 :(得分:2)
你需要进行极性分解。这篇维基百科文章解释了它的工作原理: http://en.wikipedia.org/wiki/Polar_decomposition 这是我使用OpenCV库为自己的程序编写的代码。
const double PI = 3.141592653;
cv::Mat rotationOutput = cv::Mat::zeros(warp00.size(),CV_64F);
cv::Mat_<double>::iterator rotIter = rotationOutput.begin<double>();
cv::Mat_<double>::iterator warp00Iter = warp00.begin<double>();
cv::Mat_<double>::iterator warp01Iter = warp01.begin<double>();
cv::Mat_<double>::iterator warp10Iter = warp10.begin<double>();
cv::Mat_<double>::iterator warp11Iter = warp11.begin<double>();
for(; warp00Iter != warp00.end<double>(); ++warp00Iter, ++warp01Iter, ++warp10Iter,
++warp11Iter, ++rotIter){
cv::Matx22d fMatrix(*warp00Iter,*warp01Iter, *warp10Iter, *warp11Iter);
cv::Matx22d cMatrix;
cv::Matx22d cMatSqrt(0.,0.,0.,0.);
cv::mulTransposed(fMatrix, cMatrix, true);
cv::Matx21d eigenVals;
cv::Matx22d eigenVecs;
if((cMatrix(0,0) !=0.) && (cMatrix(1,1) !=0.)){
if(cv::eigen(cMatrix,true,eigenVals,eigenVecs)){
cMatSqrt = eigenVecs.t()*
cv::Matx22d(sqrt(eigenVals(0,0)),0.,0.,sqrt(eigenVals(1,0)))*eigenVecs;
}
}
cv::Matx22d rMat = fMatrix*cMatSqrt.inv();
*rotIter = atan(rMat(1,0)/rMat(0,0));
}
&#13;
warp00,warp01,warp10和warp11包含仿射变换的前4个参数(不需要转换参数warp02和warp12)。在你的情况下,它将是a,b,c,d。 您将在维基百科文章中注意到您需要计算矩阵的平方根。唯一的方法是计算特征值,然后计算它们的平方根并将对角矩阵旋转回原始坐标系。 它很复杂,但是当你进行仿射变换时,它是计算旋转的唯一方法。 在我的情况下,我只关心旋转,所以我的代码不会给你歪斜。
答案 2 :(得分:0)
首先,您可以同时进行倾斜和旋转,但必须先选择顺序。解释了偏斜矩阵here,为您创建新矩阵的变换添加偏斜矩阵并执行yourTransformMatrix.concat(skewMatrix);
目前我无法说明您是否可以根据&#34;旋转角度&#34;,&#34; skew_X angle&#34;,&#34; skew_Y angle&#34;来检索转换值。 ,&#34; translation_X&#34;,&#34; translation_Y&#34;,这通常是一个非线性方程系统,可能没有特定矩阵的解。
答案 3 :(得分:0)
此术语是矩阵分解。这是一种解决方案,其中包括Frédéric Wang所述的偏斜。
按以下顺序应用变换时有效:倾斜,缩放,旋转,平移。
function decompose_2d_matrix(mat) {
var a = mat[0];
var b = mat[1];
var c = mat[2];
var d = mat[3];
var e = mat[4];
var f = mat[5];
var delta = a * d - b * c;
let result = {
translation: [e, f],
rotation: 0,
scale: [0, 0],
skew: [0, 0],
};
// Apply the QR-like decomposition.
if (a != 0 || b != 0) {
var r = Math.sqrt(a * a + b * b);
result.rotation = b > 0 ? Math.acos(a / r) : -Math.acos(a / r);
result.scale = [r, delta / r];
result.skew = [Math.atan((a * c + b * d) / (r * r)), 0];
} else if (c != 0 || d != 0) {
var s = Math.sqrt(c * c + d * d);
result.rotation =
Math.PI / 2 - (d > 0 ? Math.acos(-c / s) : -Math.acos(c / s));
result.scale = [delta / s, s];
result.skew = [0, Math.atan((a * c + b * d) / (s * s))];
} else {
// a = b = c = d = 0
}
return result;
}