📄 polygon.cpp
字号:
// Polygon.cpp: implementation of the CPolygon class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Polygon.h"
#include "gl/glut.h"
#include "malloc.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CPolygon::CPolygon()
{
for(int i=0;i<10;i++)
point[i].x0=point[i].y0=0;
miny=maxy=0;
pET=NULL;
AEL_head=NULL;
}
CPolygon::~CPolygon()
{
}
void CPolygon::Draw() //连接各点,画多边形
{
glBegin(GL_LINE_LOOP);
for(int i=0;i<num;i++)
glVertex2d(point[i].x0,point[i].y0);
glEnd();
glFlush();
}
int CPolygon::GetPointNum()
{
return num;
}
void CPolygon::SetPointNum(int n)
{
num=n;
}
void CPolygon::SETAELNULL(LPEdge node) //清空AEL
{
LPEdge p;
while(node)
{
p = node;
node = node->pNext;
p->pNext = NULL;
free(p);
}
}
void CPolygon::CreateET()
{
int i,j,k;
i=j=k=0;
miny=maxy=point[0].y0;
for(i=1;i<num;i++)
{
if(point[i].y0<miny)
miny=point[i].y0;
if(point[i].y0>maxy)
maxy=point[i].y0;
}
//创建ET
pET=new LPEdge[maxy-miny+1];
for(i=0;i<=maxy-miny;i++)
{
pET[i]=new Edge;
pET[i]->pNext=NULL;
}
for(i=0;i<num;i++)
{
j=(i+1)%num;
if(point[i].y0!=point[j].y0) //如果该边不是水平边
{
LPEdge peg,ppeg;
peg=new Edge;
if(point[i].y0>point[j].y0)
k=i;
else
k=j;
peg->max=point[k].y0;
if(k==j)
k=i;
else
k=j;
peg->x=(float)point[k].x0;
if(point[i].y0!=point[j].y0)
peg->dx=(float)(point[i].x0-point[j].x0)/(point[i].y0-point[j].y0);
peg->pNext=NULL;
ppeg=pET[(int)(point[k].y0-miny)];
while(ppeg->pNext)
ppeg=ppeg->pNext;
ppeg->pNext=peg;
}
}
//ET已经创建完毕
}
int CPolygon::GetProperX(LPEdge p)
{
int pointx = p->x;
if((p->x - (int)p->x) != 0)
{
if(p->dx > 0)
pointx = (int)p->x + 1;
else if(p->dx <0 )
pointx = (int)p->x;
}
else
{
if(p->dx < 0)
pointx = pointx - 1;
}
return pointx;
}
void CPolygon::AddXInAEL()
{
//将AEL中每条边的 X 值 加 deltax
LPEdge p = AEL_head;
while(p != NULL)
{
p->x += p->dx;
p = p->pNext;
}
}
void CPolygon::DeleteAEL(int currentscany)
{
//将AEL中满足 scany == ymax 的边删除
LPEdge p,p1;
p = p1= AEL_head;
while(p != NULL)
{
if(p->max == currentscany)
{
if(AEL_head == p)//如果是第一个节点
{
AEL_head = AEL_head->pNext;
p->pNext = NULL;
free(p);
p1 = p = AEL_head;//重新判断
continue;
}
else
{
p1->pNext = p->pNext;
p->pNext = NULL;
free(p);
p = p1->pNext;
}
}
else
{
p1 = p;
p = p->pNext;
}
}
}
void CPolygon::DrawCurrentscan(int currentscany)
{
LPEdge p = AEL_head;
while(p != NULL)
{
int pointx = p->x;
glBegin(GL_LINES);
pointx = GetProperX(p);
glVertex2f(pointx,currentscany);
p = p->pNext;
pointx = GetProperX(p);
glVertex2f(pointx,currentscany);
if(p != NULL)
p = p->pNext;
glEnd();
glFlush();
}
}
void CPolygon::CreateAEL(LPEdge node)
{
//将node节点指针插入到AEL,并按照一定次序排列
if(AEL_head == NULL)
AEL_head = node;
else
{
LPEdge p; //定义一个中间变量,指针的指针
for (p = node;p !=NULL;)//p = p->nextEdge)
{
//取出一个节点,并按次序插入到AEL
if(AEL_head->x >= p->x) //
{
LPEdge p1 = p->pNext;
p->pNext = AEL_head;
AEL_head = p;
p = p1;
}
else
{
LPEdge p1 = p->pNext;
p->pNext = NULL;
if(AEL_head == NULL)
AEL_head = p;
else
{
if(AEL_head->x >= p->x)
{
p->pNext = AEL_head;
AEL_head = p;
return;
}
for(LPEdge q = AEL_head;q != NULL;)
{
if(q->x <= p->x)
{
if(q->pNext == NULL)
{
q->pNext = p;
break;
}
else if(q->pNext->x > p->x)
{
p->pNext = q->pNext;
q->pNext = p;
break;
}
else
q = q->pNext;
}
}
}
p = p1;
}
}
}
}
void CPolygon::Fill()
{
CreateET();//初始化,创建边,建立ET
int scany = miny;
int scany_num = 0;
SETAELNULL(AEL_head);
glColor3f(1.0f,0.0f,0.0f);
while((AEL_head != NULL)||(pET[0]->pNext!= NULL))
{
//遍历ET对应的边结构
if(pET[(scany - miny) % (maxy-miny+1)]->pNext != NULL)
{
// scany_num ++;//根据每次AEL的变换,变换颜色,区分各个区域
glColor3f(0.3,0.6f,0.9);
CreateAEL(pET[scany - miny]->pNext);//创建AEL活化边结构
pET[scany - miny]->pNext = NULL;//将对应的ET中的边删去
}
DrawCurrentscan(scany);//画扫描线
scany ++;
DeleteAEL(scany);//将AEL中满足 scany = ymax边删除
AddXInAEL();//对AEL中剩下的每一条边的 X递增,x = deltax
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -