It wasn't quite as hard as I thought, but I did simplyfy the task by creating not a 'C' but a half circle. To create a 'C' shape you need to break the shapes into three groups: Two quarter circles and a rectangle.. Add all Shapes
to the same list!
The processing will be the same, just the math part will differ. Actually the math for the rectangle part will be even a little more involved than the extremely simple way it works for arcs :-)
Here is an example of a very simple Shape
class:
class Shape
{
public GraphicsPath Path { get; set; }
public Color FillColor { get; set; }
public Shape(GraphicsPath gp) { Path = gp; }
}
You can create a List<Shape>
for it like this:
List<Shape> FillList(int segments, int angle1, int angle2, int inner, int outer, int rings)
{
List<Shape> paths = new List<Shape>();
float deltaA = 1f * (angle2 - angle1) / segments;
float width = 1f * (outer - inner ) / rings;
for (int s = 0; s < segments; s++)
{
float a = angle1 + s * deltaA;
for (int r = 0; r < rings; r++)
{
float w1 = r * width;
float w2 = w1 + width;
GraphicsPath gp = new GraphicsPath();
RectangleF rect1 = new RectangleF(w1, w1, (outer - w1) * 2, (outer - w1) * 2);
RectangleF rect2 = new RectangleF(w2, w2, (outer - w2) * 2, (outer - w2) * 2);
gp.AddArc(rect1, a, deltaA);
gp.AddArc(rect2, a + deltaA, -deltaA);
gp.CloseFigure();
paths.Add(new Shape(gp));
}
}
return paths;
}
I have added a few NumericUpDowns
to demonstrate the parameters at work:
As you can see I color the Shapes
by selecting one and then picking a color from a palette image..
Here is the Form
's Paint
event:
private void Form1_Paint(object sender, PaintEventArgs e)
{
foreach (Shape gp in paths)
{
using (SolidBrush br = new SolidBrush(gp.FillColor))
if (gp.FillColor != null) e.Graphics.FillPath(br, gp.Path);
e.Graphics.DrawPath(Pens.Black, gp.Path);
if (gp == selected) e.Graphics.DrawPath(Pens.OrangeRed, gp.Path);
}
}
The shapes are filled with their Color if they have one and also drawn at some color; I use a fixed black Pen
for this and a red one for the Selected
shape if there is one..
The whole selection and coloring is as simple as this:
Shape selected = null;
private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
if (selected != null)
{
selected.FillColor = ((Bitmap)pictureBox1.Image).GetPixel(e.X, e.Y);
Invalidate();
}
}
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
selected = null;
foreach (Shape gp in paths)
if (gp.Path.IsVisible(e.Location)) { selected = gp; break; }
Invalidate();
}