计算机图形学 区域填充.共51页文档
- 格式:ppt
- 大小:4.74 MB
- 文档页数:51
西北农林科技大学实习报告学院名称:理学院专业班级:姓名:学号:课程:计算机图形学实验报告日期:第十四周实验三二维图形的区域填充一、实验目的1)加深对填充算法的理解,分析比较种子填充和边缘填充的差异。
2)掌握二维图形区域种子填充的原理和算法。
二、实验步骤1)对任意多边形的几何形状进行分析,选定比较合适的算法模型。
2)画出程序流程图;3)编写程序的源程序;4)编辑源程序并进行调试;5)进行特殊模式的运行测试,并结合情况进行调整。
三、实验内容用种子填充算法编写程序实现区域填充,并能在计算机上编译运行,正确地实现任意多边形边界的单色填充。
原理边界填充算法可以让用户首先勾画图的轮廓,选择填充颜色和填充模式,然后拾取内部点,系统就可以自动给图的内部涂上所需要的颜色和图案。
该算法的输入是种子点坐标 ( x , y )、填充色和边界颜色。
算法从( x , y )开始检测相邻位置是否是边界颜色,若不是,就用填充色着色,并检测其相邻位置。
该过程延续到已经检测完区域边界颜色范围内的所有像素为止。
使用栈结构来实现4-连通边界填充算法的算法步骤如下:(1)种子像素入栈。
(2)执行如下三步操作:1 栈顶像素出栈。
2 将出栈像素置成填充色。
3 检查出栈像素的4-邻接点,若其中某个像素不是边界色且未置成多边形色,则把该像素入栈。
(3)检查栈是否为空,若栈非空重复执行步骤(2),若栈为空则结束。
边界填充算法可以用于填充带有内孔的平面区域。
其缺点是把太多的像素压入堆栈,有些像素甚至会入栈多次,这样一方面降低了算法的效率,另一方面还要求很大的存储空间以实现栈结构。
将之改进,可构造沿扫描线填充水平像素段的4-连通边界填充算法,其算法步骤如下:(1)种子像素入栈。
(2)执行如下三步操作:1 栈顶元素出栈。
2 填充出栈元素所在扫描行的连续像素段,从出栈的像素开始沿扫描线向左和向右填充,直到遇到边界像素为止,即每出栈一个像素,就对包含该像素的整个扫描线区间进行填充,并且记录下此时扫描线区间的x坐标范围[ x1, x2 ]。
实验四区域填充算法的实现班级 08信计学号 58 姓名陈瑞雪分数一、实验目的和要求:1、掌握区域填充算法基本知识2、理解区域的表示和类型,能正确区分四连通和八连通的区域3、了解区域填充的实现原理,利用Microsoft Visual C++ 6.0(及EasyX_2011版)实现区域种子填充的递归算法。
二、实验内容:1、编程完成区域填色2、利用画线函数,在屏幕上定义一个封闭区域。
3、利用以下两种种子填充算法,填充上述步骤中定义的区域(1)边界表示的四连通区域种子填充的实现(2)内点表示的四连通区域种子填充的实现4、将上述算法作部分改动应用于八连通区域,构成八连通区域种子填充算法,并编程实现。
三、实验结果分析1、以上各种算法相应代码及运行结果如下:程序代码:#include<graphics.h>#include<conio.h>#include<time.h>void FloodFill4(int x,int y,int oldcolor,int newcolor){if(getpixel(x,y)==oldcolor){putpixel(x,y,newcolor);Sleep(1);FloodFill4(x-1,y,oldcolor,newcolor);FloodFill4(x,y+1,oldcolor,newcolor);FloodFill4(x+1,y,oldcolor,newcolor);FloodFill4(x,y-1,oldcolor,newcolor);}}void main(){int a,b,c,d,i,j;int graphdriver=DETECT;int graphmode=0;initgraph(&graphdriver,&graphmode," ");cleardevice();setcolor(RED);setfillstyle(RGB(255,255,0));fillcircle(315,200,50);a=300;b=200;c=RGB(255,255,0);d=RGB(0,255,0);FloodFill4(a,b,c,d);getch();closegraph();}运行结果:程序代码:#include<graphics.h>#include <conio.h>#include<time.h>void BoundaryFill4(int x,int y,int Boundarycolor,int newcolor) {if(getpixel(x,y) != newcolor && getpixel(x,y) !=Boundarycolor) {putpixel(x,y,newcolor);Sleep(1);BoundaryFill4(x-1,y,Boundarycolor,newcolor);BoundaryFill4(x,y+1,Boundarycolor,newcolor);BoundaryFill4(x+1,y,Boundarycolor,newcolor);BoundaryFill4(x,y-1,Boundarycolor,newcolor);}}void main(){int a,b,c,d,i,j;int graphdriver=DETECT;int graphmode=0;initgraph(&graphdriver,&graphmode," ");cleardevice();setcolor(RGB(0,255,0));setfillstyle(WHITE);fillellipse(50,75,150,125);a=100;b=100;c=RGB(0,255,0);d=RGB(255,0,255);BoundaryFill4(a,b,c,d);getch();closegraph();}运行结果:程序代码:#include<graphics.h>#include<conio.h>#include<time.h>void FloodFill8(int x,int y,int oldcolor,int newcolor) {if(getpixel(x,y)==oldcolor){putpixel(x,y,newcolor);Sleep(1);FloodFill8(x-1,y,oldcolor,newcolor);FloodFill8(x,y+1,oldcolor,newcolor);FloodFill8(x+1,y,oldcolor,newcolor);FloodFill8(x,y-1,oldcolor,newcolor);FloodFill8(x-1,y+1,oldcolor,newcolor);FloodFill8(x+1,y+1,oldcolor,newcolor);FloodFill8(x+1,y-1,oldcolor,newcolor);FloodFill8(x-1,y-1,oldcolor,newcolor);}}void main(){int a,b,c,d,i,j;int graphdriver=DETECT;int graphmode=0;int points[] = {250, 250, 300, 150, 350, 250,300,350};initgraph(&graphdriver,&graphmode," ");cleardevice();setcolor(GREEN);setfillstyle(RGB(0,0,255));fillpoly(4, points);a=300;b=200;c=RGB(0,0,255);d=RGB(255,255,0);FloodFill8(a,b,c,d);getch();closegraph();}运行结果:程序代码:#include<graphics.h>#include <conio.h>#include<time.h>void BoundaryFill8(int x,int y,int Boundarycolor,int newcolor){if(getpixel(x,y) != newcolor && getpixel(x,y) !=Boundarycolor) {putpixel(x,y,newcolor);Sleep(1);BoundaryFill8(x-1,y,Boundarycolor,newcolor);BoundaryFill8(x,y+1,Boundarycolor,newcolor);BoundaryFill8(x+1,y,Boundarycolor,newcolor);BoundaryFill8(x,y-1,Boundarycolor,newcolor);BoundaryFill8(x-1,y+1,Boundarycolor,newcolor);BoundaryFill8(x+1,y+1,Boundarycolor,newcolor);BoundaryFill8(x+1,y-1,Boundarycolor,newcolor);BoundaryFill8(x-1,y-1,Boundarycolor,newcolor);}}void main(){int a,b,c,d,i,j;int graphdriver=DETECT;int graphmode=0;initgraph(&graphdriver,&graphmode," ");cleardevice();setcolor(RGB(255,0,255));rectangle(170,80,270,130);for(i=171;i<270;i++)for(j=81;j<130;j++){putpixel(i,j,RGB(0,255,0));}a=200;b=100;c=RGB(255,0,255);d=RGB(0,0,255);BoundaryFill8(a,b,c,d);getch();closegraph();}运行结果:2、结果分析:通过以上各算法运行结果分析与对比可知:1.四连通算法的缺点是有时不能通过狭窄区域,因而不能填满多边形。
任课教师:李陶深教授tshli@12直线生成算法圆与椭圆的绘制算法5图元的概念436区域填充算法裁剪反走样技术4.4 区域填充算法4.4 区域填充算法—基础知识(3)线框多边形物体:只需扫描转换线段填充多边形物体:要扫描转换多边形本质:点阵表示。
特点:面着色,画面明暗自然、色彩丰富。
4.4 区域填充算法4.4 区域填充算法—基础知识(4)图形学中多边形的两种表示方式顶点表示:用多边形的有序顶点序列表示多边形点阵表示:用位于多边形内部的像素集合来表示多边形4.4 区域填充算法多边形边界的矢量形式数据之上,可用于程序填色,也可用于交互填色。
形边界的图像形式数据之上,并还需提供多边形边界内一点的坐标。
概括地说,该算法先画边界,然后对内定义区域填充。
所以,它一般只能用于人机交互填色,而难以用于程序填色。
4.4 区域填充算法—多边形填色算法的问题多边形填色算法面临的一个首要问题,是判断一个像素是在多边形内还是多边形外。
Question1: How to Judge…?Question2: How to improve …?图4.14 射线法图4.15 转角法4.4 区域填充算法4.4 区域填充算法4.4 区域填充算法4.4 区域填充算法4.4 区域填充算法大量的求交、乘除运算4.4 区域填充算法—扫描线填色算法(1)基本思路:扫描线算法按扫描线的顺序计算出扫描线与多边形的相交区间,然后用要求的颜色填充这些区间内的像素。
该算法利用了扫描线的连续性和边的连续性,避免对像素的逐点判断和反复求交运算,减少了计算量,提高了算法速度。
具体处理过程:先求出扫描线与多边形边的交点,利用扫描线的连续性求出多边形与扫描线相交的连续区域,然后利用多边形边的连续性,求出下一条扫描线与多边形的交点,对所有扫描线由上到下依次处理。
4.4 区域填充算法—扫描线填色算法(2) 算法实现的步骤:对每一条扫描线执行如下四步:(1) 求交:求扫描线与多边形各边的交点;(2) 排序:将求得的交点按递增顺序进行排序;(3) 交点配对:确定相交区间;(4) 区间填色:将相交区间内的像素置成多边形色, 相交区间外的像素置成背景色。
实验四区域填充算法的实现班级 08信计学号 67姓名张洪伟分数一、实验目的和要求:1. 理解区域的表示和类型;2.实现区域填充的扫描线算法;3.WIN-TC 图形编程模板实现编程结果并保存。
二、实验内容:在任意不间断区间中只取一个种子像素(不间断区间指在一条扫描线上一组相邻元素),填充当前扫描线上的该段区间;然后确定与这一区段相邻的上下两条扫描线上位于区域内的区段,并依次把它们保存起来,反复进行这个过程,直到所保存的每个区段都填充完毕。
1. 确定种子区段:从种子点出发,沿当前扫描线向左右两个方向填充直到边界。
用三元组(y,xLeft,xRight)记录此区段。
2.初始化:将堆栈设为空,将种子区段压入堆栈。
3.出栈:若堆栈为空,算法结束;否则取栈顶元素,以纵坐标为y的扫描线为当前扫描线,[xLeft,xRight]为搜索区间。
4.进栈:分别确定与当前扫描线相邻的上下两条扫描线与区段(y,xLeft,xRight)连通的位于给定区域内的区段。
如果有这样的区段,填充并将它们的信息压入堆栈,返回步骤3。
三、实验结果分析1该实验先用fillellipse(100,100,60,40) 画出实心椭圆,然后用如上算法填充,代码如下:setcolor(5);fillellipse(300,250,60,40);ScanLineFill(300,250,15,5);此算法还能填充带边框的多边形,如下代码填充一个矩形区域,oldColor 为背景色0:rectangle(100,20,200,50);ScanLineFill(125,30,0,5);如下代码填充带孔的四连通区域:bar(100,80,150,180);bar(150,80,200,90);bar(200,80,250,180);bar(150,130,200,180);ScanLineFill(110,150,15,2);对于每一个待填充的区段,只需压栈一次,因此扫描线算法的效率提高了很多。
区域填充算法区域填充算法
下面将介绍两种常见的区域填充算法:扫描线填充算法和种子填充算法。
1. 扫描线填充算法(Scanline Fill Algorithm):
-扫描线填充算法基于扫描线的原理,从图像的上方向下扫描,对每条扫描线上的像素进行填充。
-算法流程如下:
-选择一个初始扫描线,例如选择图像的最上面一条扫描线;
-遍历该扫描线上的每一个像素,判断是否需要填充该像素;
-如果需要填充,则向区域内部延伸扫描线,同时判断该扫描线上的相邻像素是否需要填充;
-一直延伸扫描线,直到整个区域被填充完毕。
-扫描线填充算法的优点是简单、易于实现,但是算法的效率较低,在处理大尺寸区域时耗时较长。
2. 种子填充算法(Seed Fill Algorithm):
-种子填充算法基于种子点的概念,选择一个起始点作为种子点,然后根据预设的填充规则进行填充。
-算法流程如下:
-选择一个起始点作为种子点,将该点填充上颜色;
-判断该种子点的相邻像素是否需要填充,如果需要则将其填充;
-一直延伸填充,直到整个区域被填充完毕。
-种子填充算法的优点是效率较高,能够处理较大的区域,但是需要选择合适的填充规则,否则可能会导致填充区域不准确或者出现漏填的情况。
以上两种区域填充算法在实际应用中会根据具体的场景和需求选择合适的算法进行使用。
在实际实现时,还需要考虑一些特殊情况,如图像边界处理、扫描顺序等,以确保算法的正确性和效率。