⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 polygon.cpp

📁 可以进行柱状图
💻 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 + -