最近要做个裁减的小程序,一开始本来从底层考虑算法,后来查资料发现GDI+中的Region类可以完成这个功能,于是乎,懒惰一下.下面的文字摘自说明书,也懒得改序号,大家都能看懂,哈哈
1. 主要程序及注释
3.1 运行程序
用右键拖出一个矩形,用于裁减,用左键在界面上的绘图区域绘制出一个多边形。如图1 所示。
图1 程序界面
3.1.1 绘图主要代码
3.1.1 .1 在类的构造函数中添加以下代码:
//声明一个用于存储点的列表----------
//----------------------------------
ArrayList pList = new ArrayList();
//用于绘制图形的点数组--------------
Point[] p;
//用于图形重绘的graphics类
Graphics gra ;
//定义用于裁减的区域和绘图区-------------
//---------------------
System.Drawing.Region reg,excludeReg,unionReg,intersectReg,complementReg,xorReg;
Graphics excludeGra,unionGra,intersectGra,complementGra,xorGra;
Rectangle rect;
GraphicsPath gp = new GraphicsPath();
//设置重绘标志-----------------
//-----------------------------
int x = -1;
//绘制矩形指示标志------------------
//----------------------------------
bool nRect = false;
//定义用于绘制裁减矩形的点---------
//---------------------------------
Point starpt;
Point endpt ;
//定义画笔------------------------
//--------------------------------
Pen pen = new Pen(Color.Red);
在Form_Load事件中:
private void Form1_Load(object sender, System.EventArgs e)
{
gra = panel1.CreateGraphics();
}
3.1.1 .2 在绘图区的Paint事件中添加一下代码:
if(this.nRect == true)
{
rect = new Rectangle(this.starpt.X,this.starpt.Y,this.endpt.X - this.starpt.X,this.endpt.Y - this.starpt.Y);
gra.DrawRectangle(new Pen(Color.Red),rect);
}
if(pList.Count>=1)
{
this.p = (Point[])pList.ToArray(this.pList[0].GetType());
if(pList.Count>5)
{
this.gp.Reset();
gra.DrawPolygon(new Pen(Color.WhiteSmoke),this.p);
this.gp.AddPolygon(this.p);
reg = new System.Drawing.Region(gp);
}
for(int i = 0;i<pList.Count;i++)
{
gra.DrawEllipse(new Pen(Color.HotPink),this.p[i].X-1,p[i].Y-1,2,2);
}
}
//根据标志重绘裁减区域-------------------
//-----------------------------------------
if(this.x == 5)
this.intersectGra.FillRegion(Brushes.Yellow,this.intersectReg);
if(this.x == 3)
this.unionGra.FillRegion(Brushes.Green,this.unionReg);
if(this.x == 2)
this.complementGra.FillRegion(Brushes.Aqua,this.complementReg);
if(x == 4)
this.excludeGra.FillRegion(Brushes.Red,this.excludeReg);
if(this.x == 1)
this.xorGra.FillRegion(Brushes.Black,this.xorReg);
3.1.1 .3 在mouseDown事件中处理代码如下:
if(e.Button == MouseButtons.Left)
{
this.pList.Add(new Point(e.X,e.Y));
this.panel1.Invalidate();
}
if(e.Button == MouseButtons.Right)
{
this.starpt = new Point(e.X,e.Y);
this.endpt = new Point(e.X,e.Y);
}
3.1.1 .4 在mouseMove事件的处理函数如下:
private void panel1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
if(e.Button == MouseButtons.Right)
{ //实时绘制矩形效果
Pen clearpen = new Pen(this.panel1.BackColor);
this.gra.DrawRectangle(clearpen,this.starpt.X,this.starpt.Y,this.endpt.X - this.starpt.X,this.endpt.Y - this.starpt.Y);
this.endpt = new Point(e.X,e.Y);
this.gra.DrawRectangle(this.pen,this.starpt.X,this.starpt.Y,this.endpt.X - this.starpt.X,this.endpt.Y - this.starpt.Y);
}
}
3.1.1 .5 mouseUp事件处理函数代码:
private void panel1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
if(e.Button == MouseButtons.Right)
{
this.endpt = new Point(e.X,e.Y);
this.gra.DrawRectangle(this.pen,this.starpt.X,this.starpt.Y,this.endpt.X - this.starpt.X,this.endpt.Y - this.starpt.Y);
rect = new Rectangle(this.starpt.X,this.starpt.Y,this.endpt.X - this.starpt.X,this.endpt.Y - this.starpt.Y);
this.nRect = true;
}
}
3.2 命令菜单如图2。
图2 命令菜单
3.2.1 求交处理效果见图3,函数代码如下
图3 求交效果
private void menuItem4_Click(object sender, System.EventArgs e)
{
this.intersectReg = new System.Drawing.Region(this.gp);
this.intersectGra = panel1.CreateGraphics();
try
{
//r1.Intersect(r2); 把r1更新为r1和r2的交集(即同时包含在r1和r2中的部分)
this.intersectReg.Intersect(rect);
//清除其他区域以突出显示目标区域--------------------------
//---------------------------------------------------------
if(this.excludeReg != null)
this.excludeGra.FillRegion(Brushes.Gray,this.excludeReg);
if(this.unionReg != null)
this.unionGra.Clear(this.panel1.BackColor);
if(this.xorReg != null)
this.xorGra.Clear(this.panel1.BackColor);
if(this.complementReg != null)
this.complementGra.Clear(this.panel1.BackColor);
//填充目标区域-------------------------------------
//-------------------------------------------------
this.intersectGra.FillRegion(Brushes.Yellow,this.intersectReg);
this.x = 5;
}
catch(Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
3.2.2 裁减效果见图4,代码如下
private void menuItem6_Click(object sender, System.EventArgs e)
{
this.excludeReg = new System.Drawing.Region(this.gp);
this.excludeReg.Exclude(this.rect);
// r1.Exclude(r2) 更新r1,使之不包含任何位于r2中的部分
this.excludeGra = panel1.CreateGraphics();
//清除其他区域以突出显示目标区域--------------------------
//---------------------------------------------------------
if(this.intersectReg != null)
this.intersectGra.FillRegion(Brushes.Gray,this.intersectReg);
if(this.unionReg != null)
this.unionGra.Clear(this.panel1.BackColor);
if(this.xorReg != null)
this.xorGra.Clear(this.panel1.BackColor);
if(this.complementReg != null)
this.complementGra.Clear(this.panel1.BackColor);
//填充目标区域-------------------------------------
//-------------------------------------------------
this.excludeGra.FillRegion(Brushes.Red,this.excludeReg);
this.x = 4;
}
图4 裁减效果
3.2.3 并集效果见图5,代码如下
图5 并集运算效果
private void menuItem7_Click(object sender, System.EventArgs e)
{
this.unionReg = new System.Drawing.Region(this.gp);
this.unionReg.Union(this.rect);
//r1.Union(r2); 把r1更新为r1和r2的并集(即包含在r1或r2中的部分,或同
//时包含在r1和r2中的部分)
this.unionGra = panel1.CreateGraphics();
//清除其他区域以突出显示目标区域--------------------------
//---------------------------------------------------------
if(this.intersectReg != null)
this.intersectGra.FillRegion(Brushes.Gray,this.intersectReg);
if(this.complementReg != null)
this.complementGra.Clear(this.panel1.BackColor);
if(this.xorReg != null)
this.xorGra.Clear(this.panel1.BackColor);
if(this.excludeReg != null)
this.excludeGra.Clear(this.panel1.BackColor);
//填充目标区域-------------------------------------
//-------------------------------------------------
this.unionGra.FillRegion(Brushes.Green,this.unionReg);
this.x = 3;
} .
3.2.4 异并集效果如图6,代码如下
图6 异并集效果
private void menuItem8_Click(object sender, System.EventArgs e)
{
this.xorReg = new System.Drawing.Region(this.gp);
this.xorReg.Xor(this.rect);
//r1.Xor(r2) 把r1更新为r1和r2的异并集(即包含在r1或r2中,但没有同时包含在//两者中的部分)
this.xorGra = this.panel1.CreateGraphics();
//清除其他区域以突出显示目标区域--------------------------
//---------------------------------------------------------
if(this.intersectReg != null)
this.intersectGra.FillRegion(Brushes.Gray,this.intersectReg);
if(this.unionReg != null)
this.unionGra.Clear(this.panel1.BackColor);
if(this.complementReg != null)
this.complementGra.Clear(this.panel1.BackColor);
if(this.excludeReg != null)
this.excludeGra.Clear(this.panel1.BackColor);
//填充目标区域-------------------------------------
//-------------------------------------------------
this.xorGra.FillRegion(Brushes.Black,this.xorReg);
this.x = 1;
}
3.2.5 补集效果如图7,代码如下
private void menuItem9_Click(object sender, System.EventArgs e)
{
this.complementReg = new System.Drawing.Region(this.gp);
this.complementReg.Complement(this.rect);
//r1.Complement(r2):更新r1使之包含位于r2中的部分,但不包含最初位于r1中的//部分。
this.complementGra = this.panel1.CreateGraphics();
//清除其他区域以突出显示目标区域--------------------------
//---------------------------------------------------------
if(this.intersectReg != null)
this.intersectGra.FillRegion(Brushes.Gray,this.intersectReg);
if(this.unionReg != null)
this.unionGra.Clear(this.panel1.BackColor);
if(this.xorReg != null)
this.xorGra.Clear(this.panel1.BackColor);
if(this.excludeReg != null)
this.excludeGra.Clear(this.panel1.BackColor);
//填充目标区域-------------------------------------
//-------------------------------------------------
this.complementGra.FillRegion(Brushes.Aqua,this.complementReg);
this.x = 2;
}
图7 补集效果
好了,完工了