从2d变换矩阵中提取旋转,缩放值

Tol*_*rak 21 math matrix flash-builder

如何从2d变换矩阵中提取旋转,缩放和平移值?我的意思是有一个2d的转变

matrix = [1, 0, 0, 1, 0, 0]

matrix.rotate(45 / 180 * PI)
matrix.scale(3, 4)
matrix.translate(50, 100)
matrix.rotate(30 / 180 * PI)
matrix.scale(-2, 4)
Run Code Online (Sandbox Code Playgroud)

现在我的矩阵有值[a,b,c,d,tx,ty]

让我们忘记上面的过程,并想象我们只有值a,b,c,d,tx,ty

如何通过a,b,c,d,tx,ty找到总旋转和比例值

对不起我的英语不好

谢谢你的进步

编辑

我认为应该是某个地方的答案......

我刚刚在Flash Builder(AS3)中试过这样的

   var m:Matrix = new Matrix;
   m.rotate(.25 * Math.PI);
   m.scale(4, 5);
   m.translate(100, 50);
   m.rotate(.33 * Math.PI);
   m.scale(-3, 2.5);

   var shape:Shape = new Shape;
   shape.transform.matrix = m;

   trace(shape.x, shape.y, shape.scaleX, shape.scaleY, shape.rotation);
Run Code Online (Sandbox Code Playgroud)

输出是:

x = -23.6 
y = 278.8 
scaleX = 11.627334873920528 
scaleY = -13.54222263865791 
rotation = 65.56274134518259 (in degrees)
Run Code Online (Sandbox Code Playgroud)

ja7*_*a72 42

并非所有a,b,c,d,tx,ty的值都将产生有效的旋转序列.我假设上述值是2D中3x3齐次旋转矩阵的一部分

    | a  b  tx |
A = | c  d  ty |
    | 0  0  1  |
Run Code Online (Sandbox Code Playgroud)

它将坐标[x, y, 1]转换为:

[x', y', 1] = A * |x|
                  |y|
                  |z|
Run Code Online (Sandbox Code Playgroud)
  • 从而将转换设置为 [dx, dy]=[tx, ty]
  • 规模是sx = sqrt(a² + c²)sy = sqrt(b² + d²)
  • 旋转角度t = atan(c/d)或者t = atan(-b/a)也应该是相同的.

否则,您没有有效的旋转矩阵.


上述转变扩展到:

x' = tx + sx (x Cos ? - y Sin ?)
y' = ty + sy (x Sin ? + y Cos ?)
Run Code Online (Sandbox Code Playgroud)

当订单是轮换,然后是缩放然后翻译.

  • 谢谢你的轮换和翻译...关于比例,我们得到了一个计算的单一缩放值(s = sqrt(b ^ 2 + d ^ 2))是否有可能找到scaleX和scaleY值? (3认同)
  • 由于`cos()`函数的性质,请记住`sign(a)= sign(sx)`和`sign(b)= sign(sy)`. (2认同)

小智 6

我今天遇到了这个问题,并找到了使用矩阵转换点的最简单的解决方案.这样,您可以先提取平移,然后提取旋转和缩放.

仅当x和y始终缩放相同(均匀缩放)时,此方法才有效.

鉴于你的矩阵m经历了一系列变换,

var translate:Point;
var rotate:Number;
var scale:Number;

// extract translation
var p:Point = new Point();
translate = m.transformPoint(p);
m.translate( -translate.x, -translate.y);

// extract (uniform) scale
p.x = 1.0;
p.y = 0.0;
p = m.transformPoint(p);
scale = p.length;

// and rotation
rotate = Math.atan2(p.y, p.x);
Run Code Online (Sandbox Code Playgroud)

你去!


Sim*_*amp 5

这个术语是矩阵分解。这是一个解决方案,其中包括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;
}
Run Code Online (Sandbox Code Playgroud)