Search code examples
winformsgdi

GDI arc with modification


I have problem with GDI. I do it in WinForms. There is what I got: my picture

And there is my code:

Graphics phantom = this.pictureBox1.CreateGraphics();
Pen blackPen = new Pen(Color.Black, 3);
Rectangle rect = new Rectangle(0, 0, 200, 150);
float startAngle = 180F;
float sweepAngle = 180F;
phantom.DrawArc(blackPen, rect, startAngle, sweepAngle);
phantom.Dispose();

I want to get something like that: my picture2

Really sorry for my paint skills. Is it possible to create such a thing from the arc itself or do I have to do it from an ellipse? I don't know how to go about it. Any tips are welcome. Thanks.


Solution

  • From my comments on the original post:

    You have two circles, let's call them lower and upper. Define the upper circle as a GraphicsPath and pass that to the constructor of a Region. Now pass that Region to e.Graphics via the ExcludeClip method. Now draw the lower circle, which will be missing the top part because of the clipping. Next, Reset() the Graphics and define the lower circle in a GraphicsPath. Use Graphics.Clip() this time, and chase that with drawing the upper circle. It will only be visible where the lower circle clip was.

    Proof of concept:

    Arc Thingy

    Code:

    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        Graphics phantom = e.Graphics;
        using (Pen blackPen = new Pen(Color.Black, 3))
        {
            Rectangle upper = new Rectangle(-50, -250, 300, 300);
            GraphicsPath upperGP = new GraphicsPath();
            upperGP.AddEllipse(upper);
            using (Region upperRgn = new Region(upperGP))
            {
                Rectangle lower = new Rectangle(0, 0, 200, 150);
                GraphicsPath lowerGP = new GraphicsPath();
                lowerGP.AddEllipse(lower);
    
                float startAngle = 180F;
                float sweepAngle = 180F;
    
                phantom.ExcludeClip(upperRgn);
                phantom.DrawArc(blackPen, lower, startAngle, sweepAngle);
    
                phantom.ResetClip();
                phantom.SetClip(lowerGP);
                phantom.DrawEllipse(blackPen, upper);
            }
    
    
        }
    }