Math SVG矩阵的旋转度

Math SVG矩阵的旋转度,math,matrix,svg,lua,coronasdk,Math,Matrix,Svg,Lua,Coronasdk,我正在从SVG文件中读取矩形的位置和旋转,该文件具有以下格式的矩阵: <rect transform="matrix(1.02414 -0.133308 0.122628 0.942091 190.767 780.999)" width="122" height="20"/> 现在我正试图将这些值解析为luato,但它们有一部分是错误的,在我目前的半猜测方法中,也经常出现错误我需要做什么才能将上述矩阵转换为正确的Lua旋转角度? 到目前为止,我得到的是以下内容(值数组是按SVG

我正在从SVG文件中读取矩形的位置和旋转,该文件具有以下格式的矩阵:

<rect transform="matrix(1.02414 -0.133308 0.122628 0.942091 190.767 780.999)" width="122" height="20"/>

现在我正试图将这些值解析为luato,但它们有一部分是错误的,在我目前的半猜测方法中,也经常出现错误我需要做什么才能将上述矩阵转换为正确的Lua旋转角度?

到目前为止,我得到的是以下内容(值数组是按SVG顺序排列的矩阵值)。谢谢

local x=值[5];局部y=值[6]
局部旋转=math.acos(值[1])
如果值[2]<0,则旋转=-旋转结束
旋转=数学地板(数学度(旋转))
旋转=旋转%360
精灵处理器:createBar(数学地板(x)、数学地板(y)、旋转)

首先,我认为您需要从0到5进行索引,而不是从1到6

根据,旋转矩阵为:

a  c  e
b  d  f
0  0  1
| sx 0  0|
|  0 sy 0| 
|  0  0 1|
其中a-f是矩阵列表中的6个数字

我们还发现围绕
cx,cy
旋转(角度,cx,cy)相当于

  • 翻译(cx,cy)
  • 旋转(角度)
  • 翻译(-cx,-cy)
  • 这将是:

    |1 0 cx|  |cos(t) -sin(t) 0|  |1 0 -cx|
    |0 1 cy|  |sin(t)  cos(t) 0|  |0 1 -cy|
    |0 0 1 |  |  0       0    1|  |0 0  1 |
    
      |cos(t)   -sin(t)  cx|  |1 0 -cx|
    = |sin(t)    cos(t)  cy|  |0 1 -cy|
      |   0        0      1|  |0 0  1 |
    
      |cos(t)   -sin(t)  (-cx cos(t) + cy sin(t) + cx) |
    = |sin(t)    cos(t)  (-cx sin(t) - cy cos(t) + cy) |
      |  0         0              1                    |
    
    因此,这表明角度信息在系数a、b、c和d中是完全独立的。如果唯一应用的是这个矩阵,那么a和d应该匹配,b和c应该正好是相反的符号

    然而,看看你的数字列表,它们不是,所以我想知道是否也应用了其他转换?正如评论者指出的,数字大于1,因此不是简单的角度触发操作的结果

    一种可能性是,也有一个缩放。该矩阵为:

    a  c  e
    b  d  f
    0  0  1
    
    | sx 0  0|
    |  0 sy 0| 
    |  0  0 1|
    
    如果先应用这个,然后旋转,我们会得到:

    | sx 0  0| |cos(t)   -sin(t)  (-cx cos(t) + cy sin(t) + cx) |
    |  0 sy 0| |sin(t)    cos(t)  (-cx sin(t) - cy cos(t) + cy) |
    |  0  0 1| |  0         0              1                    |
    
      |sx cos(t)   -sx sin(t)   sx (-cx cos(t) + cy sin(t) + cx) |
    = |sy sin(t)    sy cos(t)   sy (-cx sin(t) - cy cos(t) + cy) |
      |  0               0                  1                    |
    
    根据该矩阵:

    a/c = sx cos(t) / (-sx sin(t))
        = - cos(t) / sin(t)
        = 1/tan(t)
    tan(t) = c/a
    
    tan(t) = 0.122628/1.02414
           = 0.119738
        t  = 6.82794 degrees.
    
    我认为从图像上看,这是正确的

    既然我们知道了t,我们就可以算出sx和sy:

    a = sx cos(t) 
    sx = a/cos(t) = 1.0315
    
    和sy:

    d = sy cos(t)
    sy = d/cos(t) = 0.94882
    

    使用我们已经获得的值,得到cx和cy来找到旋转的中心,然后进一步代入上面e和f的方程中。

    它似乎与旋转相结合,就像
    v[4]/v[1]==-v[3]/v[2]

    因此,旋转可以这样计算:

    local str = '<rect transform="matrix(1.02414 -0.133308 0.122628 0.942091 190.767 780.999)" width="122" height="20"/>'
    local v = {}
    str:match'matrix(%b())':gsub('[%d.-]+', function(d) v[#v+1] = tonumber(d) end)
    local x, y = unpack(v, 5)
    local rotation = math.floor(math.deg(math.atan2(v[3], v[4]))) % 360
    
    localstr=''
    局部v={}
    str:match'matrix(%b())':gsub('[%d.-]+',函数(d)v[#v+1]=tonumber(d)end)
    局部x,y=拆包(v,5)
    局部旋转=数学地板(数学角度(数学角度2(v[3],v[4]))%360
    
    这不是通常的旋转矩阵,因为它包含1以上的数字。所以,arccos失败了。谢谢,你知道怎么做吗?值得注意的是,即使它是一个矩阵,比如“0.995136 0.276294-0.254158 0.91541”,cofe也无法正确地转换为度。非常感谢,这看起来很广泛!(顺便说一下,Lua数组是基于1的,因此是1到6的。)我不太知道从哪里开始使用Lua代码。你会用任何语言来解释伪代码吗?那些对t、sx和sy的计算都是伪代码。您需要的不是a、b、c、d、e、f,而是值[1]…值[6],您需要重新排列e和f项以获得cx和cy。您还需要什么?我假设您可以执行平移和缩放以及旋转。例如,对于e,你已经有了sx(-cx cos(t)+cy sin(t)+cx),而你已经有了sx和t,这给你留下了一对e和f中cx和cy的联立方程。它工作得非常好!明亮的之后,我添加了另一个“rotation=360-rotation”作为使其工作的最后一步,可能与我的代码或Corona绘图的其余部分有关。非常感谢这对我正在制作的游戏非常有帮助@PhilippLenssen-只需将
    math.atan2(v[3],v[4])
    替换为
    math.atan2(v[2],v[1])
    即可获得相反的旋转。