【发布时间】:2018-11-05 18:43:48
【问题描述】:
我正在编写一个 c++ 应用程序,它能够打开多个 SVG 文件并将它们绘制在屏幕上。其中一些包含径向梯度,其中提供了变换矩阵。在执行绘图之前,我需要计算要应用的最终渐变值,但这样做有些麻烦。
例如,考虑以下 SVG:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
id="svg2"
viewBox="0 0 250 250"
height="250"
width="250">
<defs
id="defs4">
<linearGradient
osb:paint="gradient"
id="linearGradient4162">
<stop
id="stop4164"
offset="0"
style="stop-color:#d4ca67;stop-opacity:1" />
<stop
id="stop4166"
offset="1"
style="stop-color:#64caea;stop-opacity:1;" />
</linearGradient>
<radialGradient
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.43766035,0.50852999,-0.28201922,0.24271652,332.30951,640.28863)"
spreadMethod="reflect"
r="125.35714"
fy="938.15851"
fx="14.381515"
cy="938.15851"
cx="14.381515"
id="radialGradient4172"
xlink:href="#linearGradient4162" />
</defs>
<g
transform="translate(0,-802.36216)"
id="layer1">
<path
id="rect4136"
d="m 0.45358449,802.63 250.71427551,0 0,250.3572 -250.71427551,0 z"
style="opacity:1;fill:url(#radialGradient4172);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
</g>
</svg>
绘制后,此 SVG 应给出以下结果:
在我的应用程序中,只要忽略他提供的变换矩阵,我就可以绘制 SVG。在这种情况下,我有一个连贯的结果,但当然不符合预期的结果。
现在我尝试将变换矩阵应用于径向渐变值。我得到一个完全不一致的结果。
这是我试图在我的 c++ 代码中执行的操作的伪代码,以便获得正确的转换后的渐变值:
Vector2 brushRadius(brush.Radius.Width, brush.Radius.Height);
Vector2 brushCenter(brush.Center.X, brush.Center.Y);
Vector2 brushFocus(brush.Focus.X, brush.Focus.Y);
brushRadius = brush.Matrix.Transform(brushRadius);
brushCenter = brush.Matrix.Transform(brushCenter);
brushFocus = brush.Matrix.Transform(brushFocus);
brush.m_Radius = Size(brushRadius.X, brushRadius.Y);
brush.m_Center = Point(brushCenter.X, brushCenter.Y);
brush.m_Focus = Point(brushFocus.X, brushFocus.Y);
显然这不起作用。
那么有人可以向我解释我做错了什么,以及如何将变换矩阵应用于径向梯度值以获得正确的结果?
【问题讨论】:
-
如果我在浏览器或其他渲染器中打开你的 SVG,我会得到你的第一张图片。这不是你的目标吗?你用什么渲染器?
-
我没有使用渲染器,我正在编写渲染器:-)。我的目的是编写一个在屏幕上绘制 SVG 的 c++ 应用程序。为此,我需要了解数学在幕后是如何运作的。
-
啊...从问题中我不清楚。
-
没问题。在这种情况下,我会尽量澄清我的帖子。
标签: svg matrix transform draw radial-gradients