隐藏面消除

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

隐藏面消除

✧实验目的

通过实现隐藏面算法,深入理解消隐算法的原理。

进一步熟悉OpenGL编程。

✧算法所采用的数据结构

本程序采用活化边表的扫描线Z缓冲器算法,并实现了交互界面的测试。

采用C/C++ 、OpenGL编写程序

✧主要的函数功能说明

void insertEdge(Edge *list,Edge *edge)

//在已经建立的边表中按照x坐标递增的顺序插入一条新边

void getEdgeList(int count,point *pts,Edge *edges[],int a)

//根据已给出的顶点得到边表

void sort(Edge *list,Edge *edge)

//对活化边表中的边进行排序

void getActiveList(int scan,Edge *active,Edge *edges[])

//构造活化边表

void scanfill()

//扫描填充算法的实现

✧测试用例

本程序实现一个交互输入的界面,下面是用于算法检验的数据:

2

9

90 300 110

330 380 -210

390 200 -90

180 120 200

90 300 110

120 280 100

350 220 -70

200 130 170

120 280 100

1.0 1.0 1.0 -500

4

230 250 -80

480 480 -560

430 150 -180

300 80 20

1.0 1.0 1.0 -400

得到的运行界面如下图所示:

代码附录

#include

#include

#include

#include

#include

#define SCAN_NUM 500

typedef struct Edge //边Y桶中的边结构

{

int yUpper; //边的最大y值

float xInt,dx; //边的最低点的x值,之所以是最低点,是因为本程序是从下往上扫描的

int E_mark;

float z,dzx,dzy;

struct Edge *next; //指向下一条边节点的指针

}Edge;

typedef struct point //定义一个点的结构体

{

int x;

int y;

float z;

}point;

extern point **points=NULL; //存放多个多边形的顶点信息

extern float **as=NULL; //存放多边形所在平面的方程的四个系数

extern int *counts=NULL; //存放各个多边形的顶点个数

extern int num=0; //记录多边形个数

void DrawPoint(int x, int y)//画点函数

{

::glBegin(GL_POINTS);

::glVertex2d(x, y);

::glEnd();

}

int nexty(int k,int count,point *pts)//当前测试点的下一个点的纵坐标,其方向为顺时针

{

int j;

if((k+1)>(count-1))

j=0;

else j=k+1;

while(pts[k].y==pts[j].y)

{

if((j+1)>(count-1))

j=0;

else

j++;

}

return pts[j].y;

}

void insertEdge(Edge *list,Edge *edge)//往已知边表中插入一条边,当然得按顺序插入

{

Edge *p,*q=list;

p=q->next;//p指向y=lower.y的第一条边

while(p!=NULL)

{

if(edge->xIntxInt)//测试活化边表按x增加排序,从而保证了扫描时从左往右的准确性p=NULL;

else

{

q=p; //p、q后移

p=p->next;

}

}

edge->next=q->next;//插入edge边

q->next=edge;

}

void makeEdges(point lower,point upper,int yComp,Edge *edges[],int &a)

{

Edge *edge=new Edge;

edge->dx=(float)(upper.x-lower.x)/(upper.y-lower.y);//存储当前边(lower、upper)信息

edge->xInt=(float)lower.x;//边的x坐标

if(upper.y

edge->yUpper=upper.y-1;//如果upper点非极值点

else //如果为极值点

edge->yUpper=upper.y;

edge->E_mark=a;

edge->z=lower.z;

edge->dzx=-as[a][0]/as[a][2];

edge->dzy=-as[a][1]/as[a][2];

insertEdge(edges[lower.y],edge);//将此边添加至有序边表

}

void getEdgeList(int count,point *pts,Edge *edges[],int a)

{

point v1,v2; //定义两个中间变量

int i,yPrev=pts[count-2].y;//定义yPrev为当前点的前一点纵坐标坐标

v1.x=pts[count-1].x;

v1.y=pts[count-1].y;

v1.z=pts[count-1].z;

for(i=0;i

{

v2=pts[i];//v2记录当前测试点

if(v1.y!=v2.y)//如果直线非水平的

{

if(v1.y

相关文档
最新文档