区域填充算法.docx
- 文档编号:23834449
- 上传时间:2023-05-21
- 格式:DOCX
- 页数:24
- 大小:250.33KB
区域填充算法.docx
《区域填充算法.docx》由会员分享,可在线阅读,更多相关《区域填充算法.docx(24页珍藏版)》请在冰豆网上搜索。
区域填充算法
XX大学计算机科学与技术学院
计算机科学与技术系上机实验报告
课程名称:
计算机图形学
班级:
实验日期:
2012-04-22
姓名:
学号:
指导教师:
实验序号:
4
实验成绩:
一、实验名称
1.多边形的扫描转换算法;
2.区域填充算法。
二、实验目的及要求
1.通过实验,进一步理解和掌握多边形的扫描转换算法和区域填充算法;
2.掌握以上算法实现的基本过程;
3.通过编程,会在TC或VC或Matlab环境下实现多边形的扫描转换算法和区域填充算法。
三、实验环境
1.Win7
2.VisualStudio2010
四、实验内容
1.写出多边形的扫描转换算法和区域填充算法的基本思想和公式。
并比较其特点。
2.编写用多边形的扫描转换算法和区域填充算法的程序。
并比较其结果。
3.写出上机报告
五、实验步骤及算法描述
1.依据算法、步骤编写源程序;
2.编辑源程序并进行调试;
3.进行运行测试,并结合情况进行调整;
4.对运行结果进行保存与分析;
5.打印源程序或把源程序以文件的形式提交;
6.按格式书写实验报告。
六、调试过程及实验结果
程序运行截图:
扫描线转换算法
区域填充算法
七、总结
通过这次试验,是我对多边形的扫描转换算法和区域填充算法有了更深的理解,对于两个算法个人感觉都是很精辟的,在编写程序的过程中遇到了一些困难,但是经过细心的调试和参考教课书上的算法思想,总算是实现了,总的来说这次试验锻炼了自己的编程实践能力,收获良多!
八、附录
核心代码:
多边形扫描线算法:
#region多边形扫描线算法及其相关辅助算法
#region多边形扫描线算法
publicvoidpolyFill(Graphicsg,Polygonpolygon,Colorc)
{
int[][]iMatrix=polyFill(g,polygon,c,null);
}
publicint[][]polyFill(Graphicsg,Polygonpolygon,Colorc,int[][]iMatrix)
{
intiScanLine=polygon.Y[polygon.getMaxY()]-polygon.Y[polygon.getMinY()]+1;
Console.WriteLine(iScanLine);
//新边表头指针NET[i]
ArrayList[]NET=newArrayList[iScanLine];
for(inti=0;i { //初始化新边表头指针NET[i]; NET[i]=newArrayList(); //把Ymin=i的边放进边表NET[i]; Console.WriteLine("polygon.Y[polygon.getMinY()]+i="+(polygon.Y[polygon.getMinY()]+i)); NET[i]=polygon.getYmin(polygon.Y[polygon.getMinY()]+i); } //Y=最低扫描线号; inty=polygon.Y[polygon.getMinY()]; Console.WriteLine("polygon.Y[polygon.getMinY()]="+polygon.Y[polygon.getMinY()]); //初始化活性边表AET为空; ArrayListAET=newArrayList(); for(inti=0;i { //把NET[i]中的边节点用插入排序法插入AET表,使之按x坐标递增顺序排列; InsertItem(AET,NET[i]); //遍历AET表,把配对交点区间(左闭右开)上的象素(x,y),用drawpixel(x,y,color)改写象素值; for(intj=0;j { Console.WriteLine("i="+i); OutAET(AET); //OutAET((ArrayList)AET[j+1]); intx1=(int)(getItemX((ArrayList)AET[j])+0.5); intx2=(int)(getItemX((ArrayList)AET[j+1])+0.5); inty1=i+y; if(x1==x2) { if(iMatrix==null) BaseDraw.drawPixel(g,x1,y1,c); else { iMatrix=setMatrixEle(iMatrix,polygon,x1,y1,1); } if(AET.Count%2==0) { //BaseDraw.drawPixel(g,x1,y1,c); j++; } } else { Console.WriteLine("y1="+y1+"\tx1="+x1+"\tx2="+x2); for(intl=x1;l<=x2;l++) { if(iMatrix==null) BaseDraw.drawPixel(g,l,y1,c); else { iMatrix=setMatrixEle(iMatrix,polygon,l,y1,1); } } j++; } } //Console.WriteLine("draw======================="); //OutAET(AET); //遍历AET表,把Ymax=i的结点从AET表中删除,并把Ymax>i结点的x值递增△x; Stackstack=newStack(); for(intj=0;j { //UpdateItemX(AET,j); //OutAET(AET); if(getItemYmax((ArrayList)AET[j])==i+y) { stack.Push(j); Console.WriteLine("deletei="+i+"\tj="+j+"\t(y+j)="+(y+j)+"Ymax="+getItemYmax((ArrayList)AET[j])); //AET.RemoveAt(j); } elseif(getItemYmax((ArrayList)AET[j])>i+y) UpdateItemX(AET,j); } while(stack.Count>0) { inte=(int)stack.Pop(); AET.RemoveAt(e); } //OutAET(AET); } returniMatrix; } #endregion #region对活性边表进行插入的同时排序 /// ///对活性边表进行插入的同时排序 /// /// /// protectedvoidInsertItem(ArrayLista1,ArrayLista2) { //第一步把a2中元素全部插入到a1 if(a2! =null||a2.Count! =0) for(inti=0;i { a1.Add(a2[i]); } //第二步用对a1元素进行排序 for(inti=a1.Count-1;i>0;i--) { for(intj=a1.Count-1;j>a1.Count-1-i;j--) { if(getItemX((ArrayList)a1[j-1])>getItemX((ArrayList)a1[j])) { ArrayListtemp=(ArrayList)a1[j-1]; a1[j-1]=a1[j]; a1[j]=temp; } } } } #endregion #region获得ArrayList元素的x值 /// ///获得ArrayList元素的x值 /// /// /// protectedfloatgetItemX(ArrayListlst) { if(lst==null) return0; return(float)lst[0]; } #endregion #region获得ArrayList元素的Ymax值 /// ///获得ArrayList元素的Ymax值 /// /// /// protectedintgetItemYmax(ArrayListlst) { if(lst==null) return0; return(int)lst[2]; } #endregion #region获得ArrayList元素的△x值 /// ///获得ArrayList元素的△x值 /// /// /// protectedfloatgetItemtx(ArrayListlst) { if(lst==null) return0; return(float)lst[1]; } #endregion #region更新ArrayList元素的x值使X=X+△x /// ///更新ArrayList元素的x值使X=X+△x /// /// protectedvoidUpdateItemX(ArrayListlst,intindex) { if(lst==null) return; if(index>=lst.Count) { Console.WriteLine("Err"); return; } try { //Console.WriteLine("index="+index); ArrayListl=(ArrayList)lst[index]; floatx=(float)l[0]; floattx=(float)l[1]; //四舍五入计算x x=x+tx; l[0]=x; lst[index]=l; } catch{} } #endregion #region输出活性边表,以便观察 protectedvoidOutAET(ArrayListaet) { if(aet==null) Console.WriteLine("\nEmpty! \n"); else { Console.WriteLine("========================================="); for(inti=0;i { ArrayLista=(ArrayList)aet[i]; Console.Write(getItemX(a)+""+a[1].ToString()+""+a[2].ToString()+"=="); } Console.WriteLine(""); Console.WriteLine("-----------------------------------------"); } } #endregion #endregion 区域填充算法: #region区域填充算法及其相关辅助算法 #region区域填充扫描线算法 publicvoidScanLineFill4(Graphicsg,Polygonpolygon,intx,inty,Colorc1,Colorc2) { #region旧算法无用 /* //首先把多边形区域用直线画出来 //drawPolygon(g,polygon,c); //然后填充 HashtablehashX=polygon.getX(); intiScanLine=polygon.Y[polygon.getMaxY()]-polygon.Y[polygon.getMinY()]+1; Console.WriteLine(iScanLine); for(inti=0;i { intsy=i+polygon.Y[polygon.getMinY()]; ArrayListarr=(ArrayList)hashX[sy]; for(intj=0;j { Console.Write(arr[j].ToString()+"\t"); } Console.WriteLine(""); } */ #endregion //首先画轮廓 //drawPolygon(g,polygon,c1); int[][]iPoly=polygon.getMatrix(); iPoly=this.polyFill(null,polygon,c1,iPoly); OutMatrix(iPoly); intxl,xr; boolspanNeedFill; Pointpt=newPoint(x,y); Stackstack=newStack(); //pt.X=x;pt.Y=y; stack.Push(pt); while(stack.Count>0) { pt=(Point)stack.Pop(); y=pt.Y; x=pt.X; //iPoly=setMatrixEle(iPoly,polygon,x,y,2); while(ChkMtxEle(iPoly,polygon,x,y)==1)//向左填充 { BaseDraw.drawPixel(g,x,y,Color.Red); iPoly=setMatrixEle(iPoly,polygon,x,y,2); x++; } xr=x-1; x=pt.X-1; while(ChkMtxEle(iPoly,polygon,x,y)==1)//向右填充 { BaseDraw.drawPixel(g,x,y,Color.Red); iPoly=setMatrixEle(iPoly,polygon,x,y,2); x--; } xl=x+1; //OutMatrix(iPoly); //Console.WriteLine("stack.Count="+stack.Count); //处理上面一条线 x=xl; y=y+1; while(x { spanNeedFill=false; while(ChkMtxEle(iPoly,polygon,x,y)==1) { spanNeedFill=true; x++; } if(spanNeedFill) { pt.X=x-1; pt.Y=y; stack.Push(pt); spanNeedFill=false; } while(ChkMtxEle(iPoly,polygon,x,y)! =1&&x x++; }//Endofwhile(x //处理下面一条扫描线 x=xl; y=y-2; while(x { spanNeedFill=false; while(ChkMtxEle(iPoly,polygon,x,y)==1) { spanNeedFill=true; x++; } if(spanNeedFill) { pt.X=x-1; pt.Y=y; stack.Push(pt); spanNeedFill=false; } while(ChkMtxEle(iPoly,polygon,x,y)! =1&&x x++; }//Endofwhile(x } } publicvoidScanLineFill4(Graphicsg,intx,inty,Colorc1,Colorc2) { ScanLineFill4(g,this,x,y,c1,c2); } #endregion #region检查某个点是否是边界点 /// ///检查某个点是否是边界点 /// /// /// /// /// /// protectedintChkMtxEle(int[][]iMatrix,Polygonpoly,intx,inty) { x-=poly.X[poly.getMinX()]; y-=poly.Y[poly.getMinY()]; if(0<=y&&y returniMatrix[y][x]; else return0; } #endregion #region设置矩阵某个点的值 /// ///设置矩阵某个点的值 /// /// /// /// /// protectedint[][]setMatrixEle(int[][]iMatrix,Polygonpoly,intx,inty,intiVal) { x-=poly.X[poly.getMinX()]; y-=poly.Y[poly.getMinY()]; iMatrix[y][x]=iVal; returniMatrix; } #endregion #region返回多边形交点矩阵 /// ///返回多边形交点矩阵 /// /// publicint[][]getMatrix() { int[][]iPoly=newint[Y[getMaxY()]-Y[getMinY()]+1][]; for(inti=0;i
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 区域 填充 算法