在 Inkscape 中展平 SVG 矩阵变换 [英] Flattening SVG matrix transforms in Inkscape

查看:47
本文介绍了在 Inkscape 中展平 SVG 矩阵变换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a free clip art SVG file originally created in Inkscape which I'm making modifications to for use in a Windows 8 JavaScript game. It contains numerous instances of a path with a matrix transform applied on a surrounding group, like this:

<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>

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

I want to flatten that transform by applying it in advance to the path in Inkscape, to reduce browser work during animation. However when I plug the 6 matrix values into the A B C D E F parameters in Inkscape and apply it, it gives the path a completely different rotation and scaling to what the IE10 engine does.

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

I have checked numerous times that I have the 6 values mapped correctly. What am I doing wrong?

好的,这是来自 IE10 和 Inkscape 之前和之后的屏幕截图.对于 IE10 的情况,SVG 直接位于一个原本为空的 HTML 文档的正文中(在 Firefox 中呈现完全相同).在 Inkscape 中,我只需打开仅包含路径元素的之前"SVG 文件,选择路径,然后将 6 个矩阵变换值插入到对象 > 变换 > 矩阵中.我对矩阵知之甚少,我只是希望能够以与浏览器相同的方式预先应用这些转换,并且最好理解为什么 Inkscape 存在差异.谢谢.

OK, here are before and after screenshots from IE10 and Inkscape. For the IE10 case, the SVG resides directly inside the body of an otherwise empty HTML document (the rendering is exactly the same in Firefox). In Inkscape, I simply opened the "before" SVG file which contains only the path element, selected the path, and plugged in the 6 matrix transform values into Object > Transform > Matrix. I know very little about matrices, I just want to be able to pre-apply these transformations in the same way the browser does, and ideally to understand why there is a difference in Inkscape. Thanks.

推荐答案

简短回答

在 Inkscape 中输入转换矩阵参数时,请确保已选中编辑当前矩阵",因为如果将新的转换矩阵应用于对象,实际上是将此新矩阵与对象的现有转换矩阵相乘对象,因此请务必对其进行编辑.

Short answer

When typing the transformation matrix params in Inkscape, make sure you have "Edit current matrix" checked, since if you apply a new transformation matrix to an object, you're actually multiplying this new matrix with the existing transformation matrix of the object, so make sure you edit it instead.

如何自己重新计算一切.

How to recalculate everything yourself.

首先让我们试着了解一下变换矩阵.变换矩阵是将仿射变换(保留直线的变换)应用于向量的快速而聪明的工具.
因此,如果您有一个向量(例如,二维坐标)和一个变换矩阵,并将两者相乘,您将得到变换后的坐标,并应用变换矩阵中定义的变换.

计算 x'y' 是这样完成的:

First let us try and understand the transformation matrices a bit. A transformation matrix is a quick and clever tool for applying affine transformations ( transformation which preserves straight lines) to a vector.
So, if you have a vector (say, 2d coordinates) and a transformation matrix, and multiply the two together, you will end up with transformed coordinates, with the transformations defined in the transformation matrix, applied.

Calculating x' and y' is done like so:

x' = a*x + c*y + e 
y' = b*x + d*y + f

接下来,我们需要稍微了解一下svg格式.
根据 w3c svg 规范 matrix 变换正好将这 6 个参数(a、b、c、d、e、f)作为参数.
因此,从您的示例中,

Next, we need to understand the svg format a bit.
According to the w3c svg spec the matrix transform takes exactly those 6 parameters (a,b,c,d,e,f) as arguments.
Therefore, from your example,

<g transform="matrix(0.443,0.896,-0.896,0.443,589.739,-373.223)">

我们有以下变换矩阵参数:

we have the following transformation matrix params:

a=0.443
b=0.896
c=-0.896
d=0.443
e=589.739
f=-373.223

现在,如果我们有以下示例坐标:x=27, y=-9,我们可以使用之前定义的变换矩阵来变换它,如下所示:

Now, if we have the following example coordinate: x=27, y=-9, we can transform it, by using the previously defined transformation matrix like this:

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 路径数据.
根据w3c svg path dspecification,路径数据中的每个字母代表一个操作说明.指令后面的每一对数字代表一个坐标值.

But that is not all. We also need to understand svg path data.
According to the w3c svg path dspecification each letter in the path data represents an instruction. And each of the number pairs that follow an instruction represent a coordinate value.

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

From your example, we have the following path:

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

这里我们看到这个路径对象使用了一条绝对的moveto指令(大写M),一条相对的smooth curveto三次贝塞尔曲线(小写s),一个相对的lineto指令(小写l),以及另一个相对的smooth curveto三次贝塞尔曲线指令,后跟closepath 指令(小写z).

Here we see that this path object uses one absolute moveto instruction (uppercase M), a relative smooth curveto cubic Bézier curve (lowercase s), a relative lineto instruction (lowercase l), and another relative smooth curveto cubic Bézier curve instruction, followed by a closepath instruction (lowercase z).

M486,313 被转换为 absolute moveto x=486, y=313
s27-9,43-29 读起来有点复杂,因为有些逗号被省略了,因为如果负数是负数就不需要它们,所以减号作为一个昏迷 - 无论如何,它转化为相对平滑的贝塞尔曲线到 x=27, y=-9, x=43, y=-29(一个目标点和一个控制点)
等等.

M486,313 is translated to absolute moveto x=486, y=313
s27-9,43-29 is a bit more complicated to read because some comas are omitted because they're not needed if the negative number is negative, so the minus sign acts as a coma - anyways, it translates to relative smooth bezier curveto x=27, y=-9, x=43, y=-29 (one destination point and one control point)
And so on.

那么,我们如何从您的 svg 组中应用和删除转换矩阵?像这样:

So, how do we apply and remove the transformation matrix from your svg group? Like so:

// we read the transformation matrix params
// <g transform="matrix(0.443,0.896,-0.896,0.443,589.739,-373.223)">
a=0.443
b=0.896
c=-0.896
d=0.443
e=589.739
f=-373.223

// we read the path data, and transform each instruction    
// <path d="M486,313s27-9,43-29l26,4,1,23-22,5s-25-6-48-3z" />

M486,313 绝对移动到

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.589,200.892

S27-9,43-29 - 平滑曲线,对每个坐标重复相同的过程,但设置 ef (转换参数)到 0,因为它是相对指令而不是绝对指令.
现在是
s20.025,20.205,45.033,25.6809999999999997

S27-9,43-29 - smooth curveto, repeat the same process for each coordinate, but set the e and f (translation parameters) to 0, since it's a relative instruction not an absolute.
It is now
s20.025,20.205,45.033,25.680999999999997

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

s-25-6-48-3
将成为
s-5.698999999999999,-25.058000000000003,-18.576,-44.337

并且 z 将保持 z

因此转换后的路径将是:

So the resulting transformed path will be:

<代码><路径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"/>

我希望这对你有意义.

这篇关于在 Inkscape 中展平 SVG 矩阵变换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆