matrix - 在 Inkscape 中展平 SVG 矩阵变换

标签 matrix svg transform inkscape

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

<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 引擎完全不同的旋转和缩放。

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

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

IE10 path only IE10 path with transform Inkscape path only Inkscape path with transform

最佳答案

简短回答

在 Inkscape 中输入变换矩阵参数时,请确保选中“编辑当前矩阵”,因为如果将新的变换矩阵应用于对象,实际上是将这个新矩阵与该对象的现有变换矩阵相乘。对象,因此请确保对其进行编辑。
enter image description here

长答案

如何自己重新计算一切。

首先让我们尝试稍微理解一下变换矩阵。 变换矩阵是一种快速而巧妙的工具,用于将仿射变换(保留直线的变换)应用于向量。
因此,如果您有一个向量(例如,二维坐标)和一个变换矩阵,并将两者相乘,您最终将得到变换后的坐标,并应用变换矩阵中定义的变换。
transformation matrix
计算 x'y' 如下所示:

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

接下来,我们需要了解一下 svg 格式。
根据w3c svg spec 矩阵 变换恰好采用这 6 个参数(a、b、c、d、e、f)作为参数。
因此,从你的例子来看,

<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

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

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

很整洁,是吧?您可以获取更多信息here

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

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

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

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

M486,313 被转换为绝对移动到 x=486, y=313
s27-9,43-29 读起来有点复杂,因为一些逗号被省略了,因为如果负数是负数则不需要它们,所以负号充当逗号 - 无论如何,它转换为相对平滑的贝塞尔曲线x=27、y=-9、x=43、y=-29(一个目标点和一个控制点)
等等。

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

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

因此转换后的路径将是:

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

我希望这对您有意义。

关于matrix - 在 Inkscape 中展平 SVG 矩阵变换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14684846/

相关文章:

python - 行为异常的numpy矩阵的Python列表

javascript - 使用 JavaScript 创建 SVG 组返回 falsechildren.length

css - 如何创建外侧为圆边、内侧为斜边的切换按钮?

r - 根据向量中的不同条件构建矩阵

python - 在带有标记的列和行的 python 字典中创建矩阵

css - 如何在 svg 对象标签上使用 css3 动画?

python - matplotlib 比例文本(大括号)

css - 使用 css 使用 google chrome 进行文本旋转

css - 在 Opera 中旋转

python - 在 python/numpy 中优化矩阵写入