C#在面板中绘制圆圈

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

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

这是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 ellipses = new List(); // 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. 在MouseDown事件中,捕获圆的中心(或根据偏好的边界框的顶角)的位置,以及绘制圆的事实。
  2. 在MouseMove事件中,如果正在绘制圆,则绘制圆,使用当前鼠标位置作为圆的边缘上的点(或边界框的对角,根据偏好)
  3. 在MouseUp事件中,捕获圆的半径以及不再绘制圆的事实。 将新创建的圆存储在圆形集合中,然后将其渲染到屏幕上。

在某些旧技术中,您必须在步骤2的MouseMove事件中擦除和重绘圆圈。如果您使用的是WPF或类似高级的东西,您可以在步骤1中创建一个圆形对象并将其添加到canvas中,然后在步骤2中操纵其属性.WPF引擎将负责从旧位置擦除圆圈并将其绘制到新位置。

您可以使用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(); 

使用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对象。

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

看看CodeProject上的这篇文章 ,互联网上有很多。