用GDI+进行地物矩形剪裁

最近要做个裁减的小程序,一开始本来从底层考虑算法,后来查资料发现GDI+中的Region类可以完成这个功能,于是乎,懒惰一下.下面的文字摘自说明书,也懒得改序号,大家都能看懂,哈哈

1. 主要程序及注释

3.1 运行程序

用右键拖出一个矩形,用于裁减,用左键在界面上的绘图区域绘制出一个多边形。如图1 所示。<shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"></shapetype>

<shapetype stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 414.75pt; HEIGHT: 330pt" type="#_x0000_t75"><imagedata o:title="" src="file:///C:/DOCUME~1/Game/LOCALS~1/Temp/msohtml1/12/clip_image001.png"></imagedata></shape>

程序界面

1 程序界面

<chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899"><strong style="mso-bidi-font-weight: normal"><span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 150%; FONT-FAMILY: 黑体; mso-hansi-font-family: 宋体">3.1.1</span></strong></chsdate> 绘图主要代码

<chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899">3.1.1</chsdate>.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();

}

<chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899"><strong style="mso-bidi-font-weight: normal"><span lang="EN-US" style="FONT-SIZE: 12pt; LINE-HEIGHT: 150%; FONT-FAMILY: 黑体; mso-hansi-font-family: 宋体">3.1.1</span></strong></chsdate>.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);

<chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899"><strong style="mso-bidi-font-weight: normal"><span lang="EN-US" style="FONT-SIZE: 12pt; LINE-HEIGHT: 150%; FONT-FAMILY: 黑体; mso-font-kerning: 0pt; mso-hansi-font-family: 宋体">3.1.1</span></strong></chsdate>.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);

}

<chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899"><strong style="mso-bidi-font-weight: normal"><span lang="EN-US" style="FONT-SIZE: 12pt; LINE-HEIGHT: 150%; FONT-FAMILY: 黑体; mso-font-kerning: 0pt; mso-hansi-font-family: 宋体">3.1.1</span></strong></chsdate>.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);

}

}

<chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899"><strong style="mso-bidi-font-weight: normal"><span lang="EN-US" style="FONT-SIZE: 12pt; LINE-HEIGHT: 150%; FONT-FAMILY: 黑体; mso-font-kerning: 0pt; mso-hansi-font-family: 宋体">3.1.1</span></strong></chsdate>.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

命令菜单

<shape id="_x0000_i1026" style="WIDTH: 116.25pt; HEIGHT: 113.25pt" type="#_x0000_t75"><imagedata o:title="" src="file:///C:/DOCUME~1/Game/LOCALS~1/Temp/msohtml1/12/clip_image003.png"></imagedata></shape>

2 命令菜单

<chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899"><strong style="mso-bidi-font-weight: normal"><span lang="EN-US" style="FONT-SIZE: 14pt; FONT-FAMILY: 黑体; mso-hansi-font-family: 宋体">3.2.1</span></strong></chsdate> 求交处理效果见图3,函数代码如下

求交效果

<shape id="_x0000_i1027" style="WIDTH: 414.75pt; HEIGHT: 330pt" type="#_x0000_t75"><imagedata o:title="" src="file:///C:/DOCUME~1/Game/LOCALS~1/Temp/msohtml1/12/clip_image005.png"></imagedata></shape>

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更新为r1r2的交集(即同时包含在r1r2中的部分)

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

}

}

<chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899"><strong style="mso-bidi-font-weight: normal"><span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 150%; FONT-FAMILY: 黑体; mso-font-kerning: 0pt; mso-hansi-font-family: 宋体">3.2.2</span></strong></chsdate> 裁减效果见图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;

}

裁减效果

<shape id="_x0000_i1028" style="WIDTH: 414.75pt; HEIGHT: 328.5pt" type="#_x0000_t75"><imagedata o:title="" src="file:///C:/DOCUME~1/Game/LOCALS~1/Temp/msohtml1/12/clip_image007.png"></imagedata></shape>

4 裁减效果

<chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899"><strong style="mso-bidi-font-weight: normal"><span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 150%; FONT-FAMILY: 黑体; mso-font-kerning: 0pt; mso-hansi-font-family: 宋体">3.2.3</span></strong></chsdate> 并集效果见图5,代码如下

<shape id="_x0000_i1029" style="WIDTH: 414.75pt; HEIGHT: 327.75pt" type="#_x0000_t75"><imagedata o:title="" src="file:///C:/DOCUME~1/Game/LOCALS~1/Temp/msohtml1/12/clip_image009.png"></imagedata></shape>

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更新为r1r2的并集(即包含在r1r2中的部分,或同

//时包含在r1r2中的部分)

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;

} .

<chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899"><strong style="mso-bidi-font-weight: normal"><span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 200%; FONT-FAMILY: 黑体; mso-font-kerning: 0pt; mso-hansi-font-family: 宋体">3.2.4</span></strong></chsdate> 异并集效果如图6,代码如下

异并集效果

<shape id="_x0000_i1030" style="WIDTH: 414.75pt; HEIGHT: 327.75pt" type="#_x0000_t75"><imagedata o:title="" src="file:///C:/DOCUME~1/Game/LOCALS~1/Temp/msohtml1/12/clip_image011.png"></imagedata></shape>

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更新为r1r2的异并集(即包含在r1r2中,但没有同时包含在//两者中的部分)

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;

}

<chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899"><strong style="mso-bidi-font-weight: normal"><span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 150%; FONT-FAMILY: 黑体; mso-font-kerning: 0pt; mso-hansi-font-family: 宋体">3.2.5</span></strong></chsdate> 补集效果如图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;

}

补集效果

<shape id="_x0000_i1031" style="WIDTH: 414.75pt; HEIGHT: 327.75pt" type="#_x0000_t75"><imagedata o:title="" src="file:///C:/DOCUME~1/Game/LOCALS~1/Temp/msohtml1/12/clip_image013.png"></imagedata></shape>

7 补集效果

好了,完工了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值