user717186
user717186

Reputation:

C# Drawing circles in a panel

i am doing a program on the math "Problem of Apollonius". But first my program needs to be able to allow the users to draw three circles on a panel, the circles can differ from size and position.

I cant figure out how to allow the users to draw their on size circle on the panel. Any help would be greatly appreciated.

Upvotes: 1

Views: 26101

Answers (5)

Anton Semenov
Anton Semenov

Reputation: 6347

You can draw on all winforms control using Graphics. For example:

private void button1_Click(object sender, EventArgs e)
{
  System.Drawing.Graphics g = System.Drawing.Graphics.FromHwnd(panel1.Handle);
  g.DrawEllipse(Pens.Green, panel1.ClientRectangle);
}

But in this case your painting will disappear if the form is redrawn. So you need to do it in the OnPaint method. If want to force form redrawing you can simply call the Invalidate method of your form:

this.Invalidate();

Upvotes: 2

Tergiver
Tergiver

Reputation: 14517

Here is a simple demonstration for Windows Forms.

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

// Definition for our ellipse object.
class Ellipse
{
    public int PenWidth;
    public Color Color;
    public Rectangle Rectangle;

    // Paint ourselves with the specified Graphics object
    public void Draw(Graphics graphics)
    {
        using (Pen pen = new Pen(Color, PenWidth))
            graphics.DrawEllipse(pen, Rectangle);
    }
}

class Form1 : Form
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }

    public Form1()
    {
        // Remove "flickering" from the repainting.
        SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.UserPaint, true);
    }

    // Store all created ellipses so they can be rendered during the Paint event.
    List<Ellipse> ellipses = new List<Ellipse>();

    // Definition of an Ellipse under construction
    class EllipseConstruction
    {
        public Point Origin;
        public Ellipse Ellipse;
    }

    // Storage for ellipse under construction.
    EllipseConstruction ellipseConstruction;

    // Random number generator Ellipse creation.
    private Random Rand = new Random();

    // These are the possible ellipse colors
    static readonly Color[] EllipseColors =
    {
        Color.Black,
        Color.White,
        Color.Red,
        Color.Green,
        Color.Blue,
        Color.Yellow,
        Color.Magenta,
        Color.Cyan,
    };

    protected override void OnMouseDown(MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            // Capture mouse until button up.
            Capture = true;

            // Create a new Ellipse object and record the [X, Y] origin of this click
            ellipseConstruction = new EllipseConstruction
            {
                Origin = e.Location,
                Ellipse = new Ellipse { Color = EllipseColors[Rand.Next(EllipseColors.Length)], PenWidth = Rand.Next(1, 6) },
            };
        }

        base.OnMouseDown(e);
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
        // If the mouse is captured, the user is creating a new Ellipse so we update its rectangle with the mouse coordinates
        if (Capture)
            UpdateEllipseUnderConstruction(e.Location);

        base.OnMouseMove(e);
    }

    protected override void OnMouseUp(MouseEventArgs e)
    {
        if (Capture && e.Button == MouseButtons.Left)
        {
            // If the mouse is captured and it's the Left button being released, the user is
            //   done creating a new Ellipse.

            // Stop capturing the mouse.
            Capture = false;

            // Final update of the Ellipse under construction
            UpdateEllipseUnderConstruction(e.Location);

            // Add the new Ellipse to our list unless its width or height are zero which would result in a non-visible ellipse
            if (ellipseConstruction.Ellipse.Rectangle.Width > 0 && ellipseConstruction.Ellipse.Rectangle.Height > 0)
                ellipses.Add(ellipseConstruction.Ellipse);

            // Since we are done constructing a new Ellipse, we don't need the construction object
            ellipseConstruction = null;
        }

        base.OnMouseUp(e);
    }

    protected override void OnKeyDown(KeyEventArgs e)
    {
        // Allow Ellipse creation to be cancelled with the Escape key
        if (Capture && e.KeyData == Keys.Escape)
        {
            Capture = false; // End mouse capture
            ellipseConstruction = null; // Remove construction ellipse
            Invalidate(); // Notify operating system that we need to be repainted.
        }

        base.OnKeyDown(e);
    }

    private void UpdateEllipseUnderConstruction(Point point)
    {
        // Calculate new ellipse rectangle based on ellipseConstruction.Origin and point.

        Point origin = ellipseConstruction.Origin;

        int xRadius = Math.Abs(origin.X - point.X);
        int yRadius = Math.Abs(origin.Y - point.Y);

        // Make X and Y radii the same for a true circle unless the Shift key is held down
        if ((ModifierKeys & Keys.Shift) == 0)
            xRadius = yRadius = Math.Max(xRadius, yRadius);

        ellipseConstruction.Ellipse.Rectangle = new Rectangle(origin.X - xRadius, origin.Y - yRadius, xRadius * 2, yRadius * 2);

        Invalidate(); // Notify operating system that we need to be repainted.
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        // Paint the background since we specified ControlStyles.AllPaintingInWmPaint and ControlStyles.Opaque.
        e.Graphics.Clear(Color.SlateGray);

        // Paint the ellipses we have stored.
        foreach (Ellipse ellipse in ellipses)
            ellipse.Draw(e.Graphics);

        // If the user is creating a new ellipse paint it.
        if (ellipseConstruction != null)
            ellipseConstruction.Ellipse.Draw(e.Graphics);

        base.OnPaint(e);
    }
}

Upvotes: 6

Homam
Homam

Reputation: 23861

You can draw on a panel using Graphics class in the Paint event handler of the Panel.

Have a look at this article on CodeProject and there are a lot on the internet.

Upvotes: 0

Jeffrey L Whitledge
Jeffrey L Whitledge

Reputation: 59493

  1. In the MouseDown event, capture the location of the center (or top corner of bounding box, according to preference) of the circle, and the fact that a circle is being drawn.
  2. In the MouseMove event, if a circle is being drawn, then draw the circle, using the current mouse location as a point on the edge of the circle (or opposite corner of bounding box, according to preference)
  3. In the MouseUp event, capture the radius of the circle and the fact that it is no longer being drawn. Store the newly created circle in the circle collection, and render it to the screen.

In some older technologies, you would have to erase and redraw the circle in the MouseMove event of step 2. If you are using WPF, or something similarly advanced, you can just create a circle object and add it to a canvas in step 1, and then manipulate its properties in step 2. The WPF engine will take care of erasing the circle from the old location and drawing it in the new location.

Upvotes: 3

Bogdan Verbenets
Bogdan Verbenets

Reputation: 26966

Use Graphics.DrawEllipse method:

  // Create pen.
    Pen blackPen = new Pen(Color.Black, 3);
    // Create rectangle for circle.
    Rectangle rect = new Rectangle(0, 0, 100, 100);
    // Draw circle.
    e.Graphics.DrawEllipse(blackPen, rect);

Obtain a Graphics object from your surface on which you want to draw.

Upvotes: 1

Related Questions