了解 RadialGradientBrushes 'Center'

Understanding 'Center' For RadialGradientBrushes

我很难理解 Center 属性 在 RadialGradientBrush 中的作用。 MSDN 说 'Gets or sets the center of the outermost circle of the radial gradient.' 但是当我设置它的值时,我得到的结果对我来说没有意义。

例如:

    <Rectangle Margin="10" Width="200" Height="200">
        <Rectangle.Fill>
            <RadialGradientBrush  Center="0.5,0.5">
                <GradientStop Color="Green" Offset="0" />
                <GradientStop Color="Yellow" Offset=".5" />
                <GradientStop Color="DarkRed" Offset=".5" />                        
                <GradientStop Color="Black" Offset="1.2" />
            </RadialGradientBrush>
        </Rectangle.Fill>
    </Rectangle>

使用 'Center' 的默认值,结果如下所示:

这是我所期望的。但是如果我把它改成 ="0.5,1" 我会得到这个:

从 MSDN 上,我认为它只影响最外层的圆 - 我将其解释为 'Black' GradientStop。但这似乎影响了所有人。如果我进一步移动它,它会变得更奇怪(至少对我而言)。当我将它设置为 = "0.5,3" 时,它会以开始类似于三角形的东西结束。

我进行了一些快速搜索,但没有找到对我有意义的解释。谁能解释一下 Center 到底在做什么?

刷机还有一个GradientOrigin属性,又名"focal point"。为画笔绘制的每个点计算渐变,方法是找到点沿穿过它的直线、原点和外圆之间的比例距离,并以类似于如何为线性计算阴影的方式使用该比例距离渐变画笔.

在你的每个例子中,你的原点都在中心。在第二个示例中,外圆已移动,因此它的一条边与原点重合,将停止 0 处的颜色推到该边。

第三个例子奇怪的,但恕我直言,这是采用旨在将原点置于外圆内的算法的自然结果,并用它代替填充外圆已移动到原点不再包含在中的区域。因此,根据底层算法,结果在数学上是正确的,但不再有意义。

<编辑>
"no longer make much sense",我不是指任何人,只是乍一看他们可能不是。

事实上(也许你已经对这个问题失去了兴趣……我还没有看到任何 follow-up 或其他 activity 与你有关),当你注意到这一点时选择外圈上的渐变线以定义渐变线,实际阴影会沿渐变线依次选择,结果确实有一定意义。

受到这个问题的启发,我拼凑了一个 quick-and-dirty 程序,让我可以轻松探索 RadialGradientBrush 的不同设置,并且通过交互体验,很快就清楚了该算法扩展了一条射线从原点开始,通过要着色的像素,一直到外圈(如我在上面第一段中所述)。

但有一个重要的警告:如果原点位于外圆之外,则光线延伸到的外圆点是光线从 内部接近的点 的圈子,即从外面穿过圈子后。正是这种行为导致 less-than-intuitively-obvious 输出。

在视觉上,效果是直视圆锥体,其中代码的底部由外圆描述(由 CenterRadiusXRadiusY 属性)和圆锥体的顶点由 GradientOrigin 属性 指定。如果原点在圆外,那么这个圆锥向外倾斜,顶点在底边界外,你看到的直边就是圆锥的正交投影边界。

在这种情况下查看基础 API 的文档会提供很多信息,实际上它专门将这种情况称为 "undefined"。 IE。该规范未定义任何特定行为,因此允许算法做任何它喜欢做的事情(通常是最方便的,不一定是最直观明显的)。来自 ID2D1RadialGradientBrush interface

The brush maps the gradient stop position 0.0f of the gradient origin, and the position 1.0f is mapped to the ellipse boundary. When the gradient origin is within the ellipse, the contents of the ellipse enclose the entire [0, 1] range of the brush gradient stops. If the gradient origin is outside the bounds of the ellipse, the brush still works, but its gradient is not well-defined.

事实上,至少对于当前的实现,输出是 "well-defined",因为它是可预测和可理解的(见上面的编辑)。但当然,这种行为并未 记录在案 ,并且可以随时任意更改实现。显然,用户应该将原点保持在外圈内。 :)

还要注意上面的外圈假设是1的梯度停止所在的位置。当您指定大于 1 的梯度停止时,它将位于圆的外部,并且还可能导致意外结果,具体取决于确切的几何形状。


注意:我编写的示例程序不难重新创建。但如果有兴趣,我很乐意将其包含在这里。如果有人问,我会把它添加到这个 post 中。