N点渐变画笔多边形填充

时间:2015-10-29 13:33:41

标签: c# gdi+ linear-gradients

是否可以填充N-gon,例如4点多边形,每个点具有不同的颜色并使用GDI +进行颜色混合?我正在寻找这样的东西:

3-point gradient

但是对于4点形状。

2 个答案:

答案 0 :(得分:4)

在玩弄汉斯使用路径填充的想法之后,我认为这实际上是解决这个问题的最好方法。

但是,GraphicsPathClipping都没有使用,也没有使用边界矩形。相反,我们使用一个带有点数组的特殊重载;这些点与SurroundColors的{​​{1}}属性匹配;通过这种方式,颜色不会像通常那样径向变化,而是保持固定在角点上。

以下是六个例子:

enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here

颜色列表并非完全取自光谱:

PathGradientBrush

我使用一个简单的结构来保存List<Color> colors = new List<Color>() { Color.Blue, Color.Lime, Color.Red, Color.Magenta , Color.MediumOrchid, Color.MediumSeaGreen, Color.LightSeaGreen, Color.LightSteelBlue, Color.DarkCyan}; Point

Color

我的表单有struct cPoint { public Point pt; public Color col; public cPoint(int x, int y, Color c) { pt = new Point(x,y); col = c;} } PictureBox。 NuD调用NumericUpDown

pictureBox.Paint

..调用两个函数:

private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
    pictureBox1.Invalidate();
}

private void pictureBox1_Paint(object sender, PaintEventArgs e) { points = getPolyList(colors.Take( (int) numericUpDown1.Value).ToList(), pictureBox2.ClientSize); DrawPolyGradient(e.Graphics, points, pictureBox2.ClientRectangle); } 列表是使用简单的三角函数创建的,适用于常规多边形:

cPoints

绘图代码是它自己的函数:

List<cPoint> getPolyList(List<Color> colors, Size size)
{
    int number = colors.Count;
    List<cPoint> cPoints = new List<cPoint>();

    int x2 = size.Width / 2;
    int y2 = size.Height / 2;

    for (int i = 0; i < number; i++)
    {
        double a = Math.PI / 180f * (i * 360d / number - 90);
        int x = x2 + (int)( Math.Cos(a) * (x2 - 15)); // don't overdraw
        int y = y2 + (int)( Math.Sin(a) * (x2 - 15)); // don't overdraw
        cPoints.Add(new cPoint(x, y, colors[i]));
    }
    return cPoints;
}
  • 首先计算void DrawPolyGradient(Graphics G, List<cPoint> cPoints, Rectangle bounds) { int r = 0; int g = 0; int b = 0; int c = cPoints.Count; foreach (Color col in cPoints.Select(x => x.col)) { r += col.R; g += col.G; b += col.B; } Color centercolor = Color.FromArgb(r / c, r / c, r / c); PathGradientBrush brush = new PathGradientBrush(cPoints.Select(x => x.pt).ToArray()); brush.CenterPoint = new PointF(bounds.Width / 2, bounds.Height / 2); brush.CenterColor = centercolor; brush.SurroundColors = cPoints.Select(x => x.col).ToArray(); G.FillRectangle(brush, bounds); }
  • 并设置CenterColor
  • 接下来,它会使用overload创建一个特殊CenterPoint,但不会使用PathGradientBrush而是GraphicsPath数组!

  • 这些点将对应于画笔的Point

尤其是我的第一个想法是使用简单的SurroundColors连接边缘上的点,因此无法生成更大的数字。其中许多线都会错过两者之间角落的影响。

答案 1 :(得分:0)

无法添加评论,因此为@TaW解决方案添加了次要修复程序:

Color centercolor = Color.FromArgb(r / c, r / c, r / c);

应该是

Color centercolor = Color.FromArgb(r / c, g / c, b / c);