隐藏面消除Word文档格式.docx
《隐藏面消除Word文档格式.docx》由会员分享,可在线阅读,更多相关《隐藏面消除Word文档格式.docx(13页珍藏版)》请在冰豆网上搜索。
1.01.01.0-400
得到的运行界面如下图所示:
代码附录
#include<
windows.h>
gl/gl.h>
gl/glaux.h>
gl/glu.h>
iostream.h>
#defineSCAN_NUM500
typedefstructEdge//边Y桶中的边结构
{
intyUpper;
//边的最大y值
floatxInt,dx;
//边的最低点的x值,之所以是最低点,是因为本程序是从下往上扫描的
intE_mark;
floatz,dzx,dzy;
structEdge*next;
//指向下一条边节点的指针
}Edge;
typedefstructpoint//定义一个点的结构体
intx;
inty;
floatz;
}point;
externpoint**points=NULL;
//存放多个多边形的顶点信息
externfloat**as=NULL;
//存放多边形所在平面的方程的四个系数
externint*counts=NULL;
//存放各个多边形的顶点个数
externintnum=0;
//记录多边形个数
voidDrawPoint(intx,inty)//画点函数
:
:
glBegin(GL_POINTS);
:
glVertex2d(x,y);
glEnd();
}
intnexty(intk,intcount,point*pts)//当前测试点的下一个点的纵坐标,其方向为顺时针
intj;
if((k+1)>
(count-1))
j=0;
elsej=k+1;
while(pts[k].y==pts[j].y)
{
if((j+1)>
j=0;
else
j++;
}
returnpts[j].y;
voidinsertEdge(Edge*list,Edge*edge)//往已知边表中插入一条边,当然得按顺序插入
Edge*p,*q=list;
p=q->
next;
//p指向y=lower.y的第一条边
while(p!
=NULL)
if(edge->
xInt<
p->
xInt)//测试活化边表按x增加排序,从而保证了扫描时从左往右的准确性
p=NULL;
else
{
q=p;
//p、q后移
p=p->
}
edge->
next=q->
//插入edge边
q->
next=edge;
voidmakeEdges(pointlower,pointupper,intyComp,Edge*edges[],int&
a)
Edge*edge=newEdge;
dx=(float)(upper.x-lower.x)/(upper.y-lower.y);
//存储当前边(lower、upper)信息
xInt=(float)lower.x;
//边的x坐标
if(upper.y<
yComp)
edge->
yUpper=upper.y-1;
//如果upper点非极值点
else//如果为极值点
yUpper=upper.y;
E_mark=a;
z=lower.z;
dzx=-as[a][0]/as[a][2];
dzy=-as[a][1]/as[a][2];
insertEdge(edges[lower.y],edge);
//将此边添加至有序边表
pointv1,v2;
//定义两个中间变量
inti,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<
count;
i++)
v2=pts[i];
//v2记录当前测试点
if(v1.y!
=v2.y)//如果直线非水平的
if(v1.y<
v2.y)//如果此直线是沿v1、v2方向是上升的
makeEdges(v1,v2,nexty(i,count,pts),edges,a);
else//如果此直线是沿v1、v2方向是下降的
makeEdges(v2,v1,yPrev,edges,a);
yPrev=v1.y;
v1=v2;
voiddeleteEdge(Edge*q)//删除扫描过的边
Edge*p=q->
next=p->
free(p);
voidsort(Edge*list,Edge*edge)//对活化边表中的边进行排序
E_mark<
E_mark)//首先按多边形类型进行排序,第一个排在最前面
p=NULL;
elseif(edge->
E_mark==p->
E_mark)//接着按具体某一个多边形的边的x值进行排序
{
if(edge->
p=NULL;
else
{
q=p;
p=p->
}
}
else
q=p;
p=p->
voidgetActiveList(intscan,Edge*active,Edge*edges[])//构造活化边表
Edge*p,*q;
p=edges[scan]->
//p指向edges[scan]的第一条边
while(p)
q=p->
//q指向下一条边
sort(active,p);
p=q;
Edge**edges=newEdge*[SCAN_NUM];
//边Y桶
Edge*active;
//边活化边表
inti,yscan,j;
SCAN_NUM;
edges[i]=newEdge;
//初始化有序边表
edges[i]->
next=NULL;
num;
getEdgeList(counts[i],points[i],edges,i);
//修改边Y桶
active=newEdge;
active->
intFraBuffer[SCAN_NUM][SCAN_NUM];
//创建桢缓冲器和Z缓冲器
intZBuffer[SCAN_NUM];
ZBuffer[i]=-10000;
for(j=0;
j<
j++)
FraBuffer[i][j]=-1;
for(yscan=0;
yscan<
yscan++)
getActiveList(yscan,active,edges);
//构造好活化边表
if(active->
next)
Edge*q=active,*p=active->
while(p)//遍历一趟活化边表,一次两条边,即找到一个顶点对
q=p->
for(intxx=p->
xInt;
xx<
=q->
xx++)//比较当前顶点对之间
intzz;
//点的Z值和Z缓冲器中的值
zz=p->
z+(xx-p->
xInt)*p->
dzx;
//然后确定桢缓冲器中的颜色值
if(zz>
ZBuffer[xx])//如果大,则颜色值设置为当前多边形的颜色值
{
FraBuffer[yscan][xx]=p->
E_mark;
ZBuffer[xx]=zz;
}
p=q->
for(i=0;
i++)//当前扫描线对应的桢缓冲器中的颜色值
if(FraBuffer[yscan][i]==0)//显示输出,假设本程序最多有8个多边形
:
glColor3f(1.0,0.0,0.0);
DrawPoint(i,yscan);
elseif(FraBuffer[yscan][i]==1)
glColor3f(1.0,1.0,0.0);
elseif(FraBuffer[yscan][i]==2)
glColor3f(1.0,0.0,1.0);
elseif(FraBuffer[yscan][i]==3)
glColor3f(0.0,0.1,0.2);
elseif(FraBuffer[yscan][i]==4)
glColor3f(0.2,0.1,0.0);
elseif(FraBuffer[yscan][i]==5)
glColor3f(0.1,0.2,0.0);
elseif(FraBuffer[yscan][i]==6)
glColor3f(0.1,0.2,0.2);
elseif(FraBuffer[yscan][i]==7)
glColor3f(0.4,0.6,0.3);
ZBuffer[i]=-1000;
//恢复Z缓冲器中的值,以备下次扫描时使用
//更新活化边表中具体的边中的元素值
q=active;
p=active->
//更新具体每条边的值或者删除某些边
while(p)
if(yscan>
=p->
yUpper)//当扫描线即将于某一条边分离时,删除此边
//p后移
deleteEdge(q);
p->
xInt=p->
xInt+p->
dx;
//扫描线仍与此边相交,更新下一次扫描时的x坐标的值
z+=(p->
dzx*p->
dx+p->
dzy);
//p、q后移
//更新活化边表,对更新后的边进行重新排序
//更新活化边表
active->
sort(active,p);
//调用排序函数,此函数乃是本算法的关键所在
p=q;
voidCALLBACKReshape(GLsizeiw,GLsizeih)
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(w<
=h)
gluOrtho2D(0.0,SCREEN_WIDTH,0.0,SCREEN_WIDTH*(GLfloat)h/(GLfloat)w);
else
gluOrtho2D(0.0,(GLfloat)SCREEN_WIDTH*(GLfloat)w/(GLfloat)h,0.0,SCREEN_WIDTH);
glMatrixMode(GL_MODELVIEW);
return;
voidCALLBACKDisplay1()
scanfill();
glFlush();
return;
voidInit()
auxInitDisplayMode(AUX_RGBA|AUX_SINGLE);
auxInitPosition(0,0,500,500);
auxInitWindow("
Scanalgithmic"
);
glShadeModel(GL_FLAT);
glClearColor(0.0,0.0,0.0,0.0);
voidmain(intargc,char**argv)
intx,y,z;
floata,b,c,d;
intn;
cout<
<
"
下面将一个复杂的空间图形按照其具有的平面进行输入"
endl<
endl;
请输入多边形个数:
cin>
>
points=newpoint*[num];
as=newfloat*[num];
counts=newint[num];
for(inti=0;
cout<
请输入第"
个多边形的顶点个数"
cin>
n;
counts[i]=n;
points[i]=newpoint[n];
for(intj=0;
j++)
cin>
x>
y>
z;
points[i][j].x=x;
points[i][j].y=y;
points[i][j].z=z;
as[i]=newfloat[4];
个多边形的四个系数:
a>
b>
c>
d;
as[i][0]=a;
as[i][1]=b;
as[i][2]=c;
as[i][3]=d;
Init();
auxReshapeFunc(Reshape);
auxMainLoop(Display1);