【问题标题】:Find the Rotation and Skew of a Matrix transformation求矩阵变换的旋转和偏斜
【发布时间】:2011-02-24 16:02:41
【问题描述】:

我在 CSS 中有以下变换矩阵

// rotate the element 60deg
element.style.transform = "matrix(0.5,0.866025,-0.866025,0.5,0,0)"

我可以使用这个找到旋转...

// where a = [0.710138,0.502055,-0.57735,1,0,0]
var rotation = ((180/Math.PI) * Math.atan2( ((0*a[2])+(1*a[3])),((0*a[0])-(1*a[1]))) - 90
console.log(rotation); // ~60

同样适用于偏斜如果...

// skew(30deg,-50deg) 
element.style.transform = "matrix(1,-1.19175,0.57735,1,0,0)"

var skewY = ((180/Math.PI) * Math.atan2( ((0*a[2])+(1*a[3])),((0*a[0])-(1*a[1]))) - 90;
var skewX = (180/Math.PI) * Math.atan2( ((1*a[2])+(0*a[3])),((1*a[0])-(0*a[1])));

console.log([skewX,skewY]); // ~= [30,-50] 

但是,一旦我同时使用倾斜和旋转,一切都会变得很奇怪,尤其是因为旋转的公式与倾斜的公式相同......所以公式不可能是正确的。

我如何确定两个属性都已应用且我只知道矩阵变换的旋转和倾斜。

比例尺也弄乱了我的偏斜值,我认为它不应该这样做。

【问题讨论】:

  • 有趣的问题。每个矩阵中有六个元素。这是一个 3x3 矩阵,最后一行隐式设置为 (0,0,1)?
  • 是的,javascript 中使用的变换矩阵 ( 2dcanvas 相关) 已将最新行隐式设置为 [0,0,1]
  • 我稍微完善了答案,效果很好

标签: javascript matrix qr-decomposition


【解决方案1】:

我需要相同的功能,今天我得到了这个运行良好的代码。

我从这里获得灵感: https://www.youtube.com/watch?v=51MRHjKSbtk 并且来自answer below,如果没有提示QR 分解,我永远找不到它

我处理的是 2x2 案例,我将尝试扩展到 2x3 以包括翻译。 但这应该很容易

var a = [a, b, c, d, e, f];
var qrDecompone = function(a) {
  var angle = Math.atan2(a[1], a[0]),
      denom = Math.pow(a[0], 2) + Math.pow(a[1], 2),
      scaleX = Math.sqrt(denom),
      scaleY = (a[0] * a[3] - a[2] * a[1]) / scaleX,
      skewX = Math.atan2(a[0] * a[2] + a[1] * a[3], denom);
  return {
    angle: angle / (Math.PI / 180),  // this is rotation angle in degrees
    scaleX: scaleX,                  // scaleX factor  
    scaleY: scaleY,                  // scaleY factor
    skewX: skewX / (Math.PI / 180),  // skewX angle degrees
    skewY: 0,                        // skewY angle degrees
    translateX: a[4],                // translation point  x
    translateY: a[5]                 // translation point  y
  };
};

看起来,transformMatrix 中的最后两项在分解之前是平移值。您可以直接提取它们。

【讨论】:

  • 太棒了!干得好:) 应该是公认的答案@Drew
  • 你有错误的角度吗?在哪些情况下?我经常使用这个功能,但我没有得到任何东西。有兴趣了解。
  • 我使用它来处理从 Flash 导出的 SVG,当我使用 atan2(c, a) 时,它产生了不正确的旋转值,而 atan2(b, a) 对我有用。 Andrea 向您提问:第一行 [a, c, b...] 上的矩阵顺序是否正确,或者是拼写错误?我见过的所有其他参考资料,包括下面来自 vidstige 的答案,都按字母顺序列出了各个部分。我还没有对此进行测试,但是如果切换到 [a, b, c...],而不进行任何其他代码更改,会产生一个有效的 skewX,那么这个错字就可以解释我遇到的问题。
  • @ivanreese 我很确定这是一个错字,示例应该是var a = [ a, b, c, d, e, f ];
  • 绝对是一个错字。无论如何,这个功能真的改变了我在fabric.js中可以解决的问题,我很高兴。
【解决方案2】:

找到你的矩阵的定义here。我们有变换矩阵T

    / a b tx \
T = | c d ty |
    \ 0 0 1  /

对于下面的表达式

element.style.transform = "matrix(a,b,c,d,tx,ty)"

为了检索用于构建此矩阵的参数,我们需要首先找到矩阵 T 的分解。假设在旋转后应用了倾斜,我们可以找到QR-decomposition

QR = T

旋转将在 Q 矩阵中以 旋转矩阵的形式出现。然后您可以使用三角法找出单个旋转角度,例如像这样

rotation = atan2(Q21, Q11)

偏斜和平移会在 R 矩阵中找到。

    / sx   k  tx \
R = |  0  sy  ty |
    \  0   0   1 /

其中sxsy 是比例,k 代表剪切。我不知道这个剪切与 css-skew 有什么关系。

我不知道 QR 分解在 javascript 中是否可用,但使用 Numerical Recipes 作为参考应该很容易实现。

不是获取参数以创建新矩阵对象的完整答案,但应该让您朝着正确的方向前进!

【讨论】:

  • 感谢您的回复。我暂时搁置了这个项目。当我有时间时,我会从你离开的地方继续。但它实际上是我学到的非常简单的向量矩阵。我说很简单...我还没有解决。 :)
  • 感谢我的回答:) 其实没那么简单,但绝对可行。
  • 感谢您的提示,我可以在我的答案下方找到解决方案,其中包含分解矩阵的完整代码。
猜你喜欢
  • 2011-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-26
  • 1970-01-01
相关资源
最近更新 更多