答案 0 :(得分:4)
在玩弄汉斯使用路径填充的想法之后,我认为这实际上是解决这个问题的最好方法。
但是,GraphicsPath
和Clipping
都没有使用,也没有使用边界矩形。相反,我们使用一个带有点数组的特殊重载;这些点与SurroundColors
的{{1}}属性匹配;通过这种方式,颜色不会像通常那样径向变化,而是保持固定在角点上。
以下是六个例子:
颜色列表并非完全取自光谱:
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);