Any way to easily draw a hollow donut shape in C#
So like a graphics.FillEllipse, but with a hole in the middle. I need to highlight some circular icons by putting a ring around them,开发者_开发百科 and due to the constraints of the larger program it's hard/impossible to simply FillEllipse under them to make it look like there's a hole.
// Create a brush
SolidBrush b = new SolidBrush(Color.Blue);
// Clear your Graphics object (defined externally)
gfx.Clear(Color.White);
// You need a path for the outer and inner circles
GraphicsPath path1 = new GraphicsPath();
GraphicsPath path2 = new GraphicsPath();
// Define the paths (where X, Y, and D are chosen externally)
path1.AddEllipse((float)(X - D / 2), (float)(Y - D / 2), (float)D, (float)D);
path2.AddEllipse((float)(X - D / 4), (float)(Y - D / 4), (float)(D / 2), (float)(D / 2));
// Create a region from the Outer circle.
Region region = new Region(path1);
// Exclude the Inner circle from the region
region.Exclude(path2);
// Draw the region to your Graphics object
gfx.FillRegion(b, region);
Using GDI+, you can draw a circle with a high value for the pen width, to make it look like a donut. There will be nothing in the centre so you'll be able to see through it.
You could create a Region that is based on what you would have drawn using the FillEllipse and the use the Exclude method of the Region to remove areas that you don't want by using another GraphicsPath returned from another call to FillEllipse.
Then you would just have to overlay the resulting Region on top of what you want it to surround.
Based on user263134 answer:
g.FillRegion(Brushes.Black, GetRingRegion(center, innerRadius, outherRadius));
public static RectangleF GetRectangle(PointF center, float radius)
{
var rectangle = new RectangleF(center.X - radius, center.Y - radius,radius * 2, radius * 2);
return rectangle;
}
public static Region GetRingRegion(PointF center, float innerRadius, float outherRadius)
{
// You need a path for the outer and inner circles
var path1 = new GraphicsPath();
var path2 = new GraphicsPath();
// Define the paths (where X, Y, and D are chosen externally)
path1.AddEllipse(GetRectangle(center,outherRadius));
path2.AddEllipse(GetRectangle(center, innerRadius));
// Create a region from the Outer circle.
Region region = new Region(path1);
// Exclude the Inner circle from the region
region.Exclude(path2);
return region;
}
The answer of 'sth' is pretty much what you need, but dude you can easily just use: (Graphics).DrawEllipse(new Pen(YOURCOLOR, RINGDIAMETER), center.x - radius, center.y - radius, radius * 2, radius * 2); But i think you knew this before. :)
One important thing with the answer from sth, which is the most flexible answer, is that GraphicsPath and Brush need to be disposed so put their declaration in a using statement as follows:
// Clear your Graphics object (defined externally)
gfx.Clear(Color.White);
// You need a path for the outer and inner circles
using (GraphicsPath path1 = new GraphicsPath(), path2 = new GraphicsPath())
{
// Define the paths (where X, Y, and D are chosen externally)
path1.AddEllipse((float)(X - D / 2), (float)(Y - D / 2), (float)D, (float)D);
path2.AddEllipse((float)(X - D / 4), (float)(Y - D / 4), (float)(D / 2), (float)(D / 2));
// Create a region from the Outer circle.
Region region = new Region(path1);
// Exclude the Inner circle from the region
region.Exclude(path2);
// Create a brush
using (SolidBrush b = new SolidBrush(Color.Blue))
{
// Draw the region to your Graphics object
gfx.FillRegion(b, region);
}
}
This will ensure that they are disposed when they are no longer needed.
The using is the best way to ensure that the Dispose method is called even when an exception occurs.
精彩评论