c# winform 中实现计算任意多边形面积,包括 凹多边形,线段有交叉的多边形等。具体形式如下:
目标:计算红色区域的面积
实现的方法:
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<PointF> 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<PointF> 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<List<PointF>> drawpaths = new List<List<PointF>>();
List<PointF> drawpathtemp = new List<PointF>();
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<PointF> temp = new List<PointF>();
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<PointF> item in drawpaths)
{
gp.AddPolygon(item.ToArray());
r.MakeEmpty();
r.Union(gp);
}
this.Refresh();
break;
default:
break;
}
}
}
}
操作说明:
1、新建项目,拷贝代码,编译成功后运行。
2、鼠标左键单击窗口开始画多边形,按esc键结束,同时最后一个点坐标与第一个点坐标连接。形成封闭的多边形。
3、可以画多个多边形,可以自己尝试。
4、判断点是否在区域内:鼠标右键,即会弹出框所点击的坐标是否在多边形内。
代码仅供参考,因为是自己写的demo测试程序,还没移植到我自己的工程中,所以有点乱。