【发布时间】:2025-11-14 17:20:01
【问题描述】:
我正在用 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]。
如果我理解理论,要正确绘制矩形,我应该处理以下步骤:
- 在本地文档坐标系中计算由 x1、y1、x2 和 y2 值给出的渐变画笔边界框。这应该通过将给定的梯度变换矩阵应用于从 x1、y1、x2 和 y2 计算的点来完成
- 由于渐变单元被声明为“使用中的用户空间”,因此根据线性渐变标记值和变换后的边界框计算画笔
- 将矩形坐标转换为填充,也放入文档坐标系中
- 使用之前创建的画笔,在变换后的坐标处绘制矩形
应用上述过程,我预计会达到以下结果:
但我得到了这个结果:
如果我手动更改上述源文件中的所有值,以删除所有转换并应用文档坐标中的所有值,线性渐变将正确填充到我的矩形中。因此,如果有人可以向我解释,我将非常感激
- 我在流程中做错了什么?
- 我应该如何计算线性梯度值?
- 我应该如何将梯度矩阵应用于给定的值? (即我希望将矩阵应用于值应该在文档系统坐标中转换它们,因此转换后的值应该大致给出 x1 = 0、y1 = 0、x2 = 90 和 y2 = 145 作为结果,但事实并非如此)
注意欢迎以数学形式进行演示
【问题讨论】:
标签: svg matrix gradient transformation linear-gradients