Matrix 在Inkscape中展平SVG矩阵变换

Matrix 在Inkscape中展平SVG矩阵变换,matrix,svg,transform,inkscape,Matrix,Svg,Transform,Inkscape,我有一个免费的剪贴画SVG文件,最初是在Inkscape中创建的,我正在对它进行修改,以便在Windows8JavaScript游戏中使用。它包含多个应用于周围组的矩阵变换的路径实例,如下所示: <g transform="matrix(0.443,0.896,-0.896,0.443,589.739,-373.223)"> <path d="M486,313s27-9,43-29l26,4,1,23-22,5s-25-6-48-3z" /> </g>

我有一个免费的剪贴画SVG文件,最初是在Inkscape中创建的,我正在对它进行修改,以便在Windows8JavaScript游戏中使用。它包含多个应用于周围组的矩阵变换的路径实例,如下所示:

<g transform="matrix(0.443,0.896,-0.896,0.443,589.739,-373.223)">
    <path d="M486,313s27-9,43-29l26,4,1,23-22,5s-25-6-48-3z" />
</g>
x' = a*x + c*y + e 
x' = 0.443*27 + -0.896*-9 + 589.739
x' = 609.764

y' = b*x + d*y + f
y' = 0.896*27 + 0.443*-9 -373.223
y' = −353.018

我想通过提前将变换应用到Inkscape中的路径来展平变换,以减少动画期间的浏览器工作。但是,当我将6个矩阵值插入Inkscape中的A B C D E F参数并应用它时,它为路径提供了与IE10引擎完全不同的旋转和缩放

我已多次检查是否正确映射了6个值。我做错了什么

编辑:好的,这里是IE10和Inkscape的前后截图。对于IE10,SVG直接驻留在一个空HTML文档的主体中(在Firefox中呈现方式完全相同)。在Inkscape中,我只需打开只包含path元素的“before”SVG文件,选择路径,并将6个矩阵转换值插入Object>transform>matrix。 我对矩阵知之甚少,我只是希望能够像浏览器一样预先应用这些转换,并且理想地理解Inkscape中存在差异的原因。谢谢

简短回答 在Inkscape中键入变换矩阵参数时,请确保选中了“编辑当前矩阵”,因为如果将新变换矩阵应用于对象,实际上是将此新矩阵与对象的现有变换矩阵相乘,因此请确保改为编辑它。

长话短说 如何自己重新计算一切

首先,让我们试着了解一下转换矩阵。 变换矩阵是将仿射变换(保留直线的变换)应用于向量的一种快速而巧妙的工具。
因此,如果你有一个向量(比如说,2d坐标)和一个变换矩阵,并将两者相乘,你将得到变换后的坐标,并应用变换矩阵中定义的变换。

计算
x'
y'
的方式如下:

x' = a*x + c*y + e 
y' = b*x + d*y + f
接下来,我们需要稍微了解一下svg格式。
根据矩阵变换将这6个参数(a、b、c、d、e、f)精确地作为参数。
所以从你的例子来看,

<g transform="matrix(0.443,0.896,-0.896,0.443,589.739,-373.223)">
现在,如果我们有以下示例坐标:
x=27,y=-9
,我们可以使用前面定义的变换矩阵进行变换,如下所示:

<g transform="matrix(0.443,0.896,-0.896,0.443,589.739,-373.223)">
    <path d="M486,313s27-9,43-29l26,4,1,23-22,5s-25-6-48-3z" />
</g>
x' = a*x + c*y + e 
x' = 0.443*27 + -0.896*-9 + 589.739
x' = 609.764

y' = b*x + d*y + f
y' = 0.896*27 + 0.443*-9 -373.223
y' = −353.018
整洁,嗯?你可以得到更多信息

但这还不是全部。我们还需要了解svg路径数据。
根据路径中的每个字母,数据代表一条指令。指令后面的每个数字对代表一个坐标值

根据您的示例,我们有以下路径:

<path d="M486,313s27-9,43-29l26,4,1,23-22,5s-25-6-48-3z" />
M486313绝对移动到

x' = a*x + c*y + e = a*486 + c*313 + e = 524.589
y' = b*x + d*y + f = b*486 + d*313 + f = 200.892
移动到指令现在是M524.589200.892

S27-9,43-29-平滑曲线要对每个坐标重复相同的过程,但将
e
f
(翻译参数)设置为0,因为它是相对指令而不是绝对指令。
现在是
s20.025,20.205,45.033,25.68099997

l26,4,1,23-22,5
将成为
l7.934000000000001,25.0679999998,-20.165,11.085,-14.226,-17.497

s-25-6-48-3
将成为
s-5.6989999999999,-25.05800000000003,-18.576,-44.337

z将保持z

因此,生成的转换路径将是:

<path d="M524.589,200.892s20.025,20.205,45.033,25.680999999999997l7.934000000000001,25.067999999999998,-20.165,11.085,-14.226,-17.497s-5.698999999999999,-25.058000000000003,-18.576,-44.337z" />


我希望这对您有意义。

您可以选择路径烘焙坐标,然后使用path->Union(CTRL++)。
希望这有帮助

粘贴到位可以帮助您:

  • 双击Inkscape中的组,将其输入
  • 按Ctrl+A选择组中的所有内容,然后用Ctrl+C复制这些内容
  • 双击组外部以离开组
  • 编辑>就地粘贴(Ctrl+Alt+V)–此时,组变换将应用于粘贴的对象
  • 再次分组对象(Ctrl+G)
  • 将新组移动到与原始组相同的深度,然后删除原始组。(使用XML编辑器Ctrl+Shift+X可能会更容易。)

  • 感谢ArtBIT提供的所有信息!我在一个PHP应用程序中遇到了一些问题,并编写了一个库来处理字体数据(来自SVG文件)并对其进行任何类型的转换。任何其他感兴趣的人都可以从GitHub尝试一下:

    用法示例:

    require 'easySVG.php';
    $svg = new EasySVG();
    $svg->setFont("paris-bold-webfont.svg", 100, "#000000");
    $svg->addText("Simple text display");
    $svg->addAttribute("width", "800px");
    $svg->addAttribute("height", "100px");
    echo $svg->asXML();
    
    $def = 'YOUR SVG DEFINITION HERE';
    $easySVG = new EasySVG();
    // rotate by 40°
    $rotated_def = $easySVG->defRotate($def, 40)
    // rotate by 40° with center at (200,100)
    $rotated_def2 = $easySVG->defRotate($def, 40, 200, 100)
    // scale transform : width*4
    $scaled_def = $easySVG->defScale($def, 4)
    
    SVG数据操作示例:

    require 'easySVG.php';
    $svg = new EasySVG();
    $svg->setFont("paris-bold-webfont.svg", 100, "#000000");
    $svg->addText("Simple text display");
    $svg->addAttribute("width", "800px");
    $svg->addAttribute("height", "100px");
    echo $svg->asXML();
    
    $def = 'YOUR SVG DEFINITION HERE';
    $easySVG = new EasySVG();
    // rotate by 40°
    $rotated_def = $easySVG->defRotate($def, 40)
    // rotate by 40° with center at (200,100)
    $rotated_def2 = $easySVG->defRotate($def, 40, 200, 100)
    // scale transform : width*4
    $scaled_def = $easySVG->defScale($def, 4)
    

    在回答@andraaspa之后,您还可以尝试取消分组(Ctrl-U)并再次分组(Ctrl-G)。这对我很有用。

    我建议你展示一条你认为正确的交叉链接新路径,这可能是一个很好的答案,谢谢!我需要一些时间来理解手动应用转换的过程。同时,当我在Inkscape中设置“Edit current matrix”(编辑当前矩阵)标志时,它现在确实给出了正确的视觉结果——但是,当我保存SVG文件(作为标准Inkscape或优化)时,它将与转换一起保存为单独的属性,而不是应用于路径值。我已在首选项中将“商店转换”设置为“优化”。我如何让它将转换折叠到路径中?谢谢@Tom应确保将对象解组(对象->解组或)并另存为优化。SVG但我作为测试操作的SVG文件在SVG节点内只有一个路径节点(我的问题的路径)。所以过程是:我打开它,应用transf