您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > 实验2:多边形区域扫描线填充或种子填充
计算机图形学实验报告实验2:多边形区域扫描线填充或种子填充一、实验目的1.通过实验,进一步理解和掌握几种常用多边形填充算法的基本原理2.掌握多边形区域填充算法的基本过程3.掌握在C/C++环境下用多边形填充算法编程实现指定多边形的填充。二、实验内容用种子填充算法和扫描线填充算法等任意两种算法实现指定多边形的区域填充。三、实验原理种子填充算法又称为边界填充算法。其基本思想是:从多边形区域的一个内点开始,由内向外用给定的颜色画点直到边界为止。如果边界是以一种颜色指定的,则种子填充算法可逐个像素地处理直到遇到边界颜色为止。种子填充算法常用四连通域和八连通域技术进行填充操作。四向连通填充算法:a)种子像素压入栈中;b)如果栈为空,则转e);否则转c);c)弹出一个像素,并将该像素置成填充色;并判断该像素相邻的四连通像素是否为边界色或已经置成多边形的填充色,若不是,则将该像素压入栈;d)转b);e)结束。扫描线填充算法的基本过程如下:当给定种子点(x,y)时,首先填充种子点所在扫描线上的位于给定区域的一个区段,然后确定与这一区段相连通的上、下两条扫描线上位于给定区域内的区段,并依次保存下来。反复这个过程,直到填充结束。区域填充的扫描线算法可由下列四个步骤实现:计算机图形学实验报告(1)初始化:堆栈置空。将种子点(x,y)入栈。(2)出栈:若栈空则结束。否则取栈顶元素(x,y),以y作为当前扫描线。(3)填充并确定种子点所在区段:从种子点(x,y)出发,沿当前扫描线向左、右两个方向填充,直到边界。分别标记区段的左、右端点坐标为xl和xr。(4)并确定新的种子点:在区间[xl,xr]中检查与当前扫描线y上、下相邻的两条扫描线上的象素。若存在非边界、未填充的象素,则把每一区间的最右象素作为种子点压入堆栈,返回第(2)步。四、实验步骤1.复习有关算法,明确实验目的和要求;2.依据算法思想,绘制程序流程图(指定填充多边形);3.设计程序界面,要求操作方便;4.用C/C++语言编写源程序并调试、执行(最好能用动画显示填充过程);5.分析实验结果6.对程序设计过程中出现的问题进行分析与总结;7.打印源程序或把源程序以文件的形式提交;8.按格式要求完成实验报告。五、实验结果及分析种子填充算法的优点是非常简单,缺点是需要大量栈空间来存储相邻的点。扫描线填充算法就是它的改进的方法。它是通过沿扫描线填充水平像素段,来处理四连通或八连通相邻点,这样就仅仅只需要将每个水平像素段的起始位置压入栈,而不需要将当前位置周围尚未处理的相邻像素都压入栈,从而可以节省大量的栈空间。六、实验结果计算机图形学实验报告种子填充算法扫描线填充算法七、实验主要代码计算机图形学实验报告//种子填充算法voidCZhztchView::boundaryfill4(intx,inty,intboundarycolor,intnewcolor){intcolor;CClientDCdc(this);//获取客户区设备描述表color=dc.GetPixel(x,y);if(color!=newcolor&&color!=boundarycolor){dc.SetPixel(x,y,newcolor);boundaryfill4(x,y+1,boundarycolor,newcolor);boundaryfill4(x,y-1,boundarycolor,newcolor);boundaryfill4(x-1,y,boundarycolor,newcolor);boundaryfill4(x+1,y,boundarycolor,newcolor);}}//////////////////////////////////////////////////////////////////////////////////扫描线填充算法voidCZhztchView::OnScanfill(){RedrawWindow();CDC*pDC=GetDC();CPennewpen(PS_SOLID,3,RGB(255,0,0));CPen*old=pDC-SelectObject(&newpen);spt[0]=CPoint(100,100);//绘制多边形区域spt[1]=CPoint(300,100);spt[2]=CPoint(250,250);spt[3]=CPoint(100,250);spt[4]=CPoint(150,200);spt[5]=CPoint(90,180);spt[6]=CPoint(150,150);spt[7]=CPoint(100,100);pDC-Polyline(spt,8);//pDC-SelectObject(old);//ReleaseDC(pDC);//TODO:Addyourcommandhandlercodehere计算机图形学实验报告//CDC*pDC=GetDC();CPennewpen2(PS_SOLID,1,RGB(0,255,0));CPen*old2=pDC-SelectObject(&newpen2);intj,k,s=0;intp[5];//每根扫描线交点intpmin=0,pmax=0;for(inti=0;i=6;i++)//建立边表{edge[i].dx=(float)(spt[i+1].x-spt[i].x)/(spt[i+1].y-spt[i].y);if(spt[i].y=spt[i+1].y){edge[i].num=i;edge[i].ymin=spt[i].y;edge[i].ymax=spt[i+1].y;edge[i].xmin=(float)spt[i].x;edge[i].xmax=(float)spt[i+1].x;if(spt[i+1].ypmax)pmax=spt[i+1].y;if(spt[i].ypmin)pmin=spt[i].y;}else{edge[i].num=i;edge[i].ymin=spt[i+1].y;edge[i].ymax=spt[i].y;edge[i].xmax=(float)spt[i].x;edge[i].xmin=(float)spt[i+1].x;if(spt[i].ypmax)pmax=spt[i].y;if(spt[i+1].ypmin)pmin=spt[i+1].y;}}for(intr=1;r=6;r++)//排序edge(yUpper,xIntersect),结果为从大到小{for(intq=0;q=6-r;q++){if(edge[q].yminedge[q+1].ymin){newedge[0]=edge[q];edge[q]=edge[q+1];edge[q+1]=newedge[0];}}}计算机图形学实验报告for(intscan=pmax-1;scan=pmin+1;scan--){intb=0;k=s;for(j=k;j=6;j++){if((scanedge[j].ymin)&&(scan=edge[j].ymax))//判断与线段相交{if(scan==edge[j].ymax){if(spt[edge[j].num+1].yedge[j].ymax){b++;p[b]=(int)edge[j].xmax;}elseif(spt[edge[j].num-1].yedge[j].ymax){b++;p[b]=(int)edge[j].xmax;}}if((scanedge[j].ymin)&&(scanedge[j].ymax)){b++;p[b]=(int)(edge[j].xmax+edge[j].dx*(scan-edge[j].ymax));}}//pDC-LineTo(spt[edge[0].num].x,spt[edge[0].num].y);if(scan=edge[j].ymin)//s=j;}if(b1){for(intu=1;ub;u++){pDC-MoveTo(p[u]-1,scan);u++;pDC-LineTo(p[u],scan);}}}pDC-SelectObject(old);计算机图形学实验报告pDC-SelectObject(old2);}
本文标题:实验2:多边形区域扫描线填充或种子填充
链接地址:https://www.777doc.com/doc-1509399 .html