c# 画任意多边形并判断点是否在多边形内(计算任意多边形面积)

c# winform 中实现计算任意多边形面积,包括 凹多边形,线段有交叉的多边形等。具体形式如下:

c# 画任意多边形并判断点是否在多边形内(计算任意多边形面积)_第1张图片c# 画任意多边形并判断点是否在多边形内(计算任意多边形面积)_第2张图片c# 画任意多边形并判断点是否在多边形内(计算任意多边形面积)_第3张图片

目标:计算红色区域的面积
实现的方法:
1、首先能够在鼠标点击事件、鼠标移动事件、和paint事件中实现多边形的绘制。
2、利用GraphicsPath记录多边形顶点坐标;System.Drawing.Region 记录多边形区域
3、 使用Region 变量中IsVisible方法判断新的点是否在多边形区域内。

主要代码如下(懒,没写注释,但是都不难理解的)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace functiontest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            System.Drawing.Pen pen = new Pen(Color.Red);
            if(isDrawing==1)
            {
                if(drawpaths.Count>=1)
                {
                    foreach (List drawpath in drawpaths)
                    {
                        if (drawpath.Count >= 2)
                        {
                            e.Graphics.DrawLines(pen, drawpath.ToArray());
                            if (continues.Equals(PointF.Empty) == false)
                            {
                                e.Graphics.DrawLine(pen, start, continues);
                            }
                        }
                        else
                        {
                            if(continues.Equals(PointF.Empty)==false)
                            {
                                e.Graphics.DrawLine(pen, start, continues);
                            }
                        }
                    } 
                }
                if (drawpathtemp.Count >= 2)
                {
                    e.Graphics.DrawLines(pen, drawpathtemp.ToArray());
                    if (continues.Equals(PointF.Empty) == false)
                    {
                        e.Graphics.DrawLine(pen, start, continues);
                    }
                }
                else
                {
                    if (continues.Equals(PointF.Empty) == false)
                    {
                        e.Graphics.DrawLine(pen, start, continues);
                    }
                }      
            }
            else if(isDrawing==0)
            {
                foreach (List drawpath in drawpaths)
                {
                    if (drawpath.Count >= 2)
                    {
                        e.Graphics.DrawLines(pen, drawpath.ToArray());
                    }
                }
            }

        }
        Region r = new System.Drawing.Region();
        PointF start = PointF.Empty;
        PointF continues = PointF.Empty;
        PointF end = PointF.Empty;
        int isDrawing = 0;
        List> drawpaths = new List>();
        List drawpathtemp = new List();
        private void Form1_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (isDrawing==0)
                {
                    start = e.Location;
                    isDrawing = 1;
                    drawpathtemp.Add(start);
                }
                else if(isDrawing==1)
                {
                    start = e.Location;
                    drawpathtemp.Add(start);
                }
                else if(isDrawing==2)
                {

                }
                this.Refresh();
            }
            if (e.Button == MouseButtons.Right)
            {
                if (r.IsVisible(e.Location))
                {
                    MessageBox.Show("在选中区域内");
                }
                else
                {
                    MessageBox.Show("不在选中区域内");
                }
            }            
        }

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            if(isDrawing==1)
            {
                continues = e.Location;
                this.Refresh();
            }

        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            switch(e.KeyCode)
            {
                case Keys.Escape:
                    drawpathtemp.Add(drawpathtemp.ElementAt(0));
                    List temp = new List();
                    if(drawpathtemp.Count>2)
                    {
                        temp = drawpathtemp.GetRange(0, drawpathtemp.Count);
                        drawpaths.Add(temp);
                    }
                    drawpathtemp.Clear();
                    start = PointF.Empty;
                    end = PointF.Empty;
                    continues = PointF.Empty;
                    isDrawing = 0;
                    GraphicsPath gp = new GraphicsPath();
                    gp.Reset();
                    foreach (List item in drawpaths)
                    {
                        gp.AddPolygon(item.ToArray());
                        r.MakeEmpty();
                        r.Union(gp);
                    }
                    this.Refresh();
                    break;
                default:
                    break;
            }
        }
    }
}

操作说明:
1、新建项目,拷贝代码,编译成功后运行。
2、鼠标左键单击窗口开始画多边形,按esc键结束,同时最后一个点坐标与第一个点坐标连接。形成封闭的多边形。
3、可以画多个多边形,可以自己尝试。
4、判断点是否在区域内:鼠标右键,即会弹出框所点击的坐标是否在多边形内。

代码仅供参考,因为是自己写的demo测试程序,还没移植到我自己的工程中,所以有点乱。

你可能感兴趣的:(C#)