实验六 扫描线填充算法

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验六扫描线填充算法

一、实验目的

编写多边形的扫描线填充算法程序,加深对扫描线算法的理解,验证算法的正确性。

二、实验任务(2学时)

编写多边形的扫描线填充算法程序,利用数组实现AET,考虑与链表实现程序的不同。

三、实验内容

1、算法

对一条扫描线的填充一般分为以下4个步骤:

(1)求交:计算扫描线与多边形各边的交点;

(2)排序:把扫描线上所有交点按递增顺序进行排序;

(3)配对:将第一个交点与第二个交点,第三个交点与第四个交点等等进行配对,每对交点代表扫描线与多边形的一个相交区间。

(4)着色:把区间内的像素置为填充色。

2、成员函数的关系

主程序名为fill_area(count, x, y),其中参数x, y是两个一维数组,存放多边形顶点(共c ount个)的x和y坐标。它调用8个子程序,彼此之间的调用关系图1所示为:

图1 fill_area的程序结构

3、算法的程序设计

步骤1:创建“S_L_Fill”工程文件;

步骤2:创建类class:“EACH_ENTRY”。

在工作区“S_L_Fill classes”单击右键-→“new class”-→选择类型“Generic Class”名称为“EACH_ENTRY”,添加成员变量(添加至“class EACH_ENTRY { public:”之内):int y_top;

float x_int;

int delta_y;

float x_change_per_scan;

步骤3:包含头文件,同时初始化定义多边形顶点数目。在“class CS_L_FillView : public Cview……”之前添加代码“#include EACH_ENTRY.h”及“#define MAX_POINT 9”。

#define MAX_POINT 9

#include "EACH_ENTRY.h"

步骤4:在类“class CS_L_FillView”中添加成员变量(鼠标双击工作区“CS_L_FillView”,代码添加至“class CS_L_FillView : public Cview {protected: ……public:之后”):EACH_ENTRY sides[MAX_POINT];

int x[MAX_POINT],y[MAX_POINT];

int side_count,first_s,last_s,scan,bottomscan,x_int_count;

步骤5:利用构造函数“CS_L_FillView::CS_L_FillView()”初始化顶点坐标(鼠标双击工作区“CS_L_FillView”,代码添加至“CS_L_FillView()之内”):

x[0]=200;y[0]=100;

x[1]=240;y[1]=160;

x[2]=220;y[2]=340;

x[3]=330;y[3]=100;

x[4]=400;y[4]=180;

x[5]=300;y[5]=400;

x[6]=170;y[6]=380;

x[7]=120;y[7]=440;

x[8]=100;y[8]=220;

步骤6:在“class CS_L_FillView”下添加实现不同功能的成员函数。在工作区“CS_L_FillView”上单击鼠标右键,选择“Add Member Function”,分别完成以下成员函数的添加:

(1)void put_in_sides_list(int entry,int x1,int y1,int x2,int y2,int next_y)

函数说明:put_in_sides_list子程序的主要功能是将一条边存入活性边表之内。操作步骤是:对该边判别是否左顶点或右顶点,如果将入边之终点删去,按照y_top的大小在活性边表中找到该点的合适位置,y值较大者,排在活性边表的靠前位置。

void put_in_sides_list(int entry,int x1,int y1,int x2,int y2,int next_y)// entry为剔除水平边之后的第entry条边,x1, y1,为起点,x2, y2为终点,next_y为终点相邻的下一个顶点y坐标{

int maxy;

float x2_temp,x_change_temp;

x_change_temp=(float)(x2-x1)/(float)(y2-y1);//计算1/k

x2_temp=float(x2);

if((y2>y1)&&(y2

{

y2--;

x2_temp-=x_change_temp;

}

else

{

if((y2next_y)) //x2,y2是右顶点,则(x2+1/m,y2+1)终点上缩

{

y2++;

x2_temp+=x_change_temp;

}

}

maxy=(y1>y2)?y1:y2;

while((entry>1)&&(maxy>sides[entry-2].y_top))

{

sides[entry-1]=sides[entry-2];

entry--;

}// sides[]为边数组,边的y_top值越小,在数组中越靠后

sides[entry-1].y_top=maxy;

sides[entry-1].delta_y=abs(y2-y1)+1;

if(y1>y2)// x2,y2为右顶点,扫描线与起点先求交

sides[entry-1].x_int=float(x1);

else// x2,y2左顶点,扫描线与终点先求交

sides[entry-1].x_int=x2_temp;

sides[entry-1].x_change_per_scan=x_change_temp;

}

(2)void sort_on_bigger_y(int n,CDC* pDC)

函数说明:sort_on_bigger_y子程序的主要功能是按照输入的多边形,建立起活性边表。操作步骤是:对每条边加以判断:如非水平边则调用put_in_side_list子程序放入活性边来;如是水平边则直接画出。

void sort_on_bigger_y(int n,CDC* pDC)//按照输入的多边形建立活性链表

{

int k,x1,y1;

side_count=0;//全局变量,记录所有非水平边数目

y1=y[n-1];

x1=x[n-1];//(Pn-1,P0)为第一条边,开始建表

bottomscan=y[n-1];

for(k=0;k

{

if(y1!=y[k]&&(k+1)<=(n-1))

{

side_count++;

put_in_sides_list(side_count,x1,y1,x[k],y[k],y[k+1]);

相关文档
最新文档