使用PathGradientBrush在三角形上的颜色渐变

时间:2016-10-21 12:19:36

标签: c# .net winforms colors

我有一个三角形,每个节点都附有一个值(例如(A,B,C) -> (0.3, 0.1, 0.7))。使用以下函数将值映射到RGB颜色(0.0:蓝色,0.5:绿色,1.0:红色):

var color =  Color.FromArgb(alpha,
    (int)((value > 0.5 ? 2*value - 1 : 0) * 255),
    (int) ((value > 0.5 ? 2-2*value : 2*value) * 255),
    (int)((value > 0.5 ? 0 : (1 - 2 * value)) * 255)
);

这些值意味着在三角形上线性插值(例如重心坐标重量),并且在整个应用中它是一个更大的三角形网格。

对于绘图,我创建了一个GraphicsPath,在三个角的每个角上都有点,中间有几个点(示例中有12个可能是矫枉过正)。在PathGradientBrush上,我将SurroundColors颜色设置为角点的值或这些颜色之间的线性插值。 CenterPointCenterValue设置为(A+B+C)/3values.Sum()/3。这看起来很适合某些值(这里是(0.0, 0.5, 1.0)

good looking example

但对其他人不太好(这里(0.3, 0.8, 1.0),请看三角形顶部的工件):

not so good looking example

我尝试了其他几种策略(例如,通过到中心点的距离来加权值,将中心放在其他地方等等)但仍然得到那些文物。我只需要三角形,但绘图必须在Paint-handler中进行,手动绘制太慢。我怎么能

  • 要么摆脱中心色,要么像OpenGL
  • 那样得到彩色三角形
  • 或获得不会导致这些文物的中心值和/或位置。

重现问题和玩游戏的代码(将其粘贴到问题中有点太多):http://pastebin.com/gjjzqRvY

1 个答案:

答案 0 :(得分:0)

我不记得上次没有回答我自己的问题了。

PathGradientBrush

之间的颜色进行线性插值
  • 周围的点 - >边界上的每个点都有一个颜色符号
  • 边界和中心点上的插值颜色

    这与以下颜色映射非常吻合:

    var color = Color.FromArgb(alpha,     (int)(值* 255),     (int)((1-value)* 255),     0 );

例如:如果边从0变为1,则画笔的插值将计算为30%:

0.3 * colorA + 0.7 * colorB
= 0.3 * (0, 255, 0) + 0.7 * (255,0,0)
= (76, 178)

这正是0.3的colormapping-function的结果。这同样适用于朝向中心的第二次插值。

但我有3种颜色但幸运的是只有一个极端点在0.5。 0.0 .. 0.5工作正常,0.5 .. 1.0工作正常。但这是线性插值分解。诀窍是给渐变画笔这个极端点:

  • 角落的最小值和最大值不会超过魔术点,只需使用中心值。
  • 如果他们交叉,找到他们所在的边缘和点。总有两个。画笔的中心点是它们的平均值,值是极值点。

暗示未来的读者:

  • 如果你的映射不是线性的(平方根,sin / cos,log,...)你运气不好
  • 如果您的地图有超过1个极端点,那么您将失去运气
  • 路径上的
  • 3(不交叉)或5(交叉)点就足够了。将额外的2个点设置为交叉点。