SVG - 如何将渐变变换矩阵应用于线性渐变画笔?

时间:2018-01-20 16:39:32

标签: svg matrix gradient transformation linear-gradients

我正在用c ++语言编写SVG查看器应用程序。我实际上在几个SVG文件中遇到了转换问题,我无法弄清楚。

考虑以下SVG文件:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg id="svg9686" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="90mm" width="145mm" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 145 90" xmlns:dc="http://purl.org/dc/elements/1.1/">
 <defs id="defs9680">
  <linearGradient id="linearGradient6593-0" gradientUnits="userSpaceOnUse" x1="74.658" y1="-398.92" x2="75.519" y2="-485.7" gradientTransform="matrix(1.0069 0 0 1.19 1.4571 709.77)">
   <stop id="stop6595" stop-color="#be245a" offset="0"/>
   <stop id="stop6600" stop-color="#e46e6f" offset=".48408"/>
   <stop id="stop6597" stop-color="#f1a769" offset="1"/>
  </linearGradient>
 </defs>
 <g id="layer1" transform="translate(-7.631 -139.36)">
  <rect id="rect3690-4-2-09-4-2-8-0" height="90" width="145" y="139.36" x="7.631" fill="url(#linearGradient6593-0)"/>
 </g>
</svg>

这基本上是一个填充渐变画笔的矩形,从橙色到洋红色。矩形大小为90x145,在应用所有变换后位于坐标[0,0]处。

如果我理解这个理论,要正确绘制矩形,我应该处理以下步骤:

  1. 在本地文档坐标系中计算由x1,y1,x2和y2值给出的渐变画笔边界框。这应该通过将给定的梯度变换矩阵应用于从x1,y1,x2和y2计算的点来完成
  2. 由于渐变单位被声明为“使用中的用户空间”,因此请根据线性渐变标记值和转换后的边界框计算画笔
  3. 将矩形坐标转换为填充,也将其放入文档坐标系
  4. 使用先前创建的画笔,以变换后的坐标
  5. 绘制矩形

    应用上述过程,我希望得到以下结果:

    enter image description here

    但我得到了这个结果:

    enter image description here

    如果我手动更改上述源文件中的所有值,要删除所有转换并应用文档坐标中的所有值,则在我的矩形中正确填充线性渐变。出于这个原因,如果有人能向我解释,我会非常感激

    1. 我的过程中出错了什么?
    2. 我应该如何计算线性渐变值?
    3. 如何将渐变矩阵应用于给定值? (即我期望将矩阵应用于值应该在文档系统坐标中进行转换,因此转换后的值应该大致给出x1 = 0,y1 = 0,x2 = 90和y2 = 145,但事实并非如此)
    4. 注意欢迎使用数学形式的演示

1 个答案:

答案 0 :(得分:3)

首先,使用术语&#34;边界框&#34;对于渐变我认为没有帮助。四个值x1,x2,y1,y2描述了渐变停止匹配的向量,并且梯度法线垂直于该向量(在应用任何变换之前)。 A&#34;框&#34;与渐变属性无关。

渐变矢量可以显示为线元素

<line x1="74.658" y1="-398.92" x2="75.519" y2="-485.7" />

第一步是申请gradientTransform="matrix(1.0069 0 0 1.19 1.4571 709.77)"。生成的行将绘制为

<line x1="76.6302" y1="235.055" x2="77.4972" y2="131.787" />

(由于变换不引入倾斜,因此渐变法线仍然垂直于该线。)

此时,渐变应用于其局部坐标系中的矩形

<rect width="145" height="90" x="7.631" y="139.36"/>
<line x1="76.6302" y1="235.055" x2="77.4972" y2="131.787" />

只有在此之后,最终的transform="translate(-7.631 -139.36)"才会应用于矩形和矢量:

<rect width="145" height="90" x="7.631" y="139.36"/>
<line x1="70" y1="95.7" x2="69.87" y2="-7.57" />

请注意,如果转换已直接应用于rect而不是封闭组,则甚至会出现这种情况。将变换应用于元素始终是最后要执行的操作。

我认为,在您将变换应用于矩形后,将userSpaceOnUse解释为最终坐标系时,您出错了。但它是什么,是coordinate system

  

在引用渐变元素时就位,

因此之前进一步转换。