C#在面板中绘制圆圈

时间:2011-04-20 13:08:12

标签: c#

我正在做一个关于数学“Apollonius问题”的程序。但首先我的程序需要允许用户在面板上绘制三个圆圈,圆圈可以与大小和位置不同。

我无法弄清楚如何让用户在面板上绘制他们的大小圆圈。任何帮助将不胜感激。

5 个答案:

答案 0 :(得分:6)

以下是Windows窗体的简单演示。

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);
    }
}

答案 1 :(得分:3)

  1. 在MouseDown事件中,捕获圆圈的中心位置(或根据喜好的边界框的顶角)以及正在绘制圆的事实。
  2. 在MouseMove事件中,如果正在绘制圆,则使用当前鼠标位置作为圆的边缘(或边界框的对角,根据偏好)使用当前鼠标位置绘制圆圈。
  3. 在MouseUp事件中,捕获圆的半径以及不再绘制圆的事实。将新创建的圆圈存储在圆圈集合中,然后将其渲染到屏幕上。
  4. 在某些较旧的技术中,您必须在步骤2的MouseMove事件中擦除和重绘圆圈。如果您使用的是WPF或类似高级的东西,则可以创建一个圆形对象并将其添加到画布中步骤1,然后在步骤2中操作其属性.WPF引擎将负责从旧位置擦除圆圈并将其绘制到新位置。

答案 2 :(得分:1)

您可以使用Graphics绘制所有winforms控件。例如:

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

但是在这种情况下,如果重新绘制表单,您的绘画将会消失。所以你需要在OnPaint方法中做到这一点。如果要强制重绘表单,只需调用表单的Invalidate方法:

this.Invalidate();

答案 3 :(得分:0)

使用Graphics.DrawEllipse方法:

  // 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);

从您想要绘制的曲面中获取Graphics对象。

答案 4 :(得分:0)

您可以使用Panel的Graphics事件处理程序中的Paint类在面板上绘图。

在CodeProject上查看这个article,互联网上有很多。