多边形扫面线填充算法

#include<windows.h>
#include<GL/glut.h>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<GL/gl.h>
#include<GL/glu.h>
#ifdef __APPLE__
#else
#endif
#include <stdlib.h>
using namespace std;/**
GLenum errorCheck()
{
    GLenum code;
    const GLubyte *str;
    code=glGetError();
    if(code!=GL_NO_ERROR)
    {
        str=gluErrorString(code);
        fprintf(stderr,"OpenGL error: %s\n",str);
    }
    return code;
}
void init(void)
{
    glClearColor(1.0,1.0,1.0,0.0);
    glMatrixMode(GL_PROJECTION);
    gluOrtho2D(0.0,200.0,0.0,150.0);
}
void lineSegment(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(0.1,0.4,0.2);
    glLineWidth(12.0);
    glBegin(GL_LINES);
        glVertex2i(180,15);
        glVertex2i(10,145);
    glEnd();
    glBegin(GL_LINES);
        glVertex2i(15,180);
        glVertex2i(145,10);
    glEnd();
    glFlush();

}
int main(int argc, char **argv)
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
    glutInitWindowPosition(50,100);
    glutInitWindowSize(400,300);
    glutCreateWindow("ÃȱÈÈø±È!");
    init();
    glutDisplayFunc(lineSegment);
    glutMainLoop();
}
#include <iostream.h>
#include <GL/glut.h>
//#include<Windows.h>
#include <math.h>
#include <stdlib.h>
**/
//#pragma comment(lib, "Kernel32.lib")
#define ROUND(a) ((int)(a+0.5))
#define  M  8             //定义多边形的顶点数+1
#define maxx 600
#define maxy 400
int max,min;
GLsizei winWidth = 600, winHeight = 400;
float myabs(float aa)
{
	return aa>0 ? aa:aa*(-1);
}
struct active_edge_table
{ //定义新边表的链表结点数据
	float x;
	float m;
	int ymin;
	struct active_edge_table *next;
};
struct active_edge_table *NET[maxy]; //定义新边表的Y桶指针数组

struct active_edge_table *insert_node(struct active_edge_table *head, struct active_edge_table *stud);

//活化边表插入结点操作

struct active_edge_table * del_node(struct active_edge_table * head,int ys); //活化边表删除结点

int y_min(int a[]); //取数组的最小值

int y_max(int a[]); //取数组的最大值

void polyNet(int px[M],int py[M]); //创建新边表的Y桶指针数组函数

int y_min(int a[])
{
	int j,min;
	min=a[0];
	for(j=1;j<M-1;j++)
		if(a[j]<min)min=a[j];
		return(min);
}
int y_max(int a[])
{
	int j,max=a[0];
	for(j=1;j<M-1;j++)
		if(a[j]>max)max=a[j];
		return(max);
}
//创建新边表的Y桶指针数组函数
void polyNet(int px[],int py[])
{
	//请同学们完成创建新边表的Y桶指针数组函数;
	int ymin,ymax;
	ymin=y_min(py);
	ymax=y_max(py);

	int j=0,i=0,m=0;

    for(int y=ymax;y>=ymin;y--)
	{
		for(j=0;j<M-1;j++)
			if(py[j]==y)
			{
				if(j==0)
				{
					if(py[j+1]<py[j]&&py[M-2]<py[j])
					{
						struct active_edge_table aa;
						struct active_edge_table bb;
						aa.m=float(px[j+1]-px[j])/(py[j+1]-py[j]);
						aa.m=myabs(aa.m);
						if(px[j+1]>px[j])
							aa.m=myabs(aa.m);
						else
							aa.m=aa.m*(-1);
						aa.x=px[j]+aa.m;
						aa.ymin=py[j+1];
						bb.m=float(px[M-2]-px[j])/(py[M-2]-py[j]);
						bb.m=myabs(bb.m);
						if(px[M-2]>px[j])
							bb.m=myabs(bb.m);
						else
							bb.m=bb.m*(-1);
						bb.x=px[j]+bb.m;
						bb.ymin=py[M-2];
						bb.next=NULL;
						struct active_edge_table *p;

						if(NET[y-1]==NULL)
						{
							NET[y-1]=new struct active_edge_table;
							NET[y-1]->m=aa.m;
							NET[y-1]->x=aa.x;
							NET[y-1]->ymin=aa.ymin;
							NET[y-1]->next=new struct active_edge_table;
							NET[y-1]->next->m=bb.m;
							NET[y-1]->next->ymin=bb.ymin;
							NET[y-1]->next->x=bb.x;
							NET[y-1]->next->next=bb.next;
						}
						else
						{
							p=NET[y-1];
							while(p->next!=NULL)
							{
								p=p->next;
							}
							p->next=new struct active_edge_table;
                            struct active_edge_table *q;
							q=p->next;
							q->m=aa.m;
							q->x=aa.x;
							q->ymin=aa.ymin;
							q->next=new struct active_edge_table;
							q->next->m=bb.m;
							q->next->ymin=bb.ymin;
							q->next->x=bb.x;
							q->next->next=bb.next;
						}
						continue;
					}

					if(py[j+1]>py[j]&&py[M-2]>py[j])
						continue;

					if(py[j+1]>py[j]&&py[M-2]<py[j])
					{
						struct active_edge_table bbb;
						bbb.m=float(px[M-2]-px[j])/(py[M-2]-py[j]);
						bbb.m=myabs(bbb.m);
						if(px[M-2]>px[j])
							bbb.m=myabs(bbb.m);
						else
							bbb.m=bbb.m*(-1);
						bbb.x=px[j]+bbb.m;
						bbb.ymin=py[M-2];
						bbb.next=NULL;
						struct active_edge_table *p;
						if(NET[y-1]==NULL)
						{
							NET[y-1]=new struct active_edge_table;
							NET[y-1]->m=bbb.m;
							NET[y-1]->x=bbb.x;
							NET[y-1]->ymin=bbb.ymin;
							NET[y-1]->next=NULL;
						}
						else
						{
							p=NET[y-1];
							while(p->next!=NULL)
							{
								p=p->next;
							}
							p->next=new struct active_edge_table;
							struct active_edge_table *q;
							q=p->next;
							q->m=bbb.m;
							q->x=bbb.x;
							q->ymin=bbb.ymin;
							q->next=NULL;


						}
						continue;
					}
					if(py[j+1]<py[j]&&py[M-2]>py[j])
					{
						struct active_edge_table aaa;
						aaa.m=float(px[j+1]-px[j])/(py[j+1]-py[j]);
						aaa.m=myabs(aaa.m);
						if(px[j+1]>px[j])
							aaa.m=myabs(aaa.m);
						else
							aaa.m=aaa.m*(-1);
						aaa.x=px[j]+aaa.m;
						aaa.ymin=py[j+1];
						aaa.next=NULL;
						struct active_edge_table *p;
						if(NET[y-1]==NULL)
						{
							NET[y-1]=new struct active_edge_table;
							NET[y-1]->m=aaa.m;
							NET[y-1]->x=aaa.x;
							NET[y-1]->ymin=aaa.ymin;
							NET[y-1]->next=NULL;
						}
						else
						{
							p=NET[y-1];
							while(p->next!=NULL)
							{
								p=p->next;
							}
							p->next=new struct active_edge_table;
							struct active_edge_table *q;
							q=p->next;
							q->m=aaa.m;
							q->x=aaa.x;
							q->ymin=aaa.ymin;
							q->next=NULL;
						}
						continue;
					}
					if(py[j+1]==py[j]&&py[M-2]<py[j])
					{
						struct active_edge_table aaa;
						aaa.m=float(px[M-2]-px[j])/(py[M-2]-py[j]);
						aaa.m=myabs(aaa.m);
						if(px[M-2]>px[j])
							aaa.m=myabs(aaa.m);
						else
							aaa.m=aaa.m*(-1);
						aaa.x=px[j]+aaa.m;
						aaa.ymin=py[M-2];
						aaa.next=NULL;
						struct active_edge_table *p;
						if(NET[y-1]==NULL)
						{
							NET[y-1]=new struct active_edge_table;
							NET[y-1]->m=aaa.m;
							NET[y-1]->x=aaa.x;
							NET[y-1]->ymin=aaa.ymin;
							NET[y-1]->next=NULL;
						}
						else
						{
							p=NET[y-1];
							while(p->next!=NULL)
							{
								p=p->next;
							}
							p->next=new struct active_edge_table;
							struct active_edge_table *q;
							q=p->next;
							q->m=aaa.m;
							q->x=aaa.x;
							q->ymin=aaa.ymin;
							q->next=NULL;
						}

						continue;

					}

					if(py[j+1]<py[j]&&py[M-2]==py[j])
					{
						struct active_edge_table aaa;
						aaa.m=float(px[j+1]-px[j])/(py[j+1]-py[j]);
						aaa.m=myabs(aaa.m);
						if(px[j+1]>px[j])
							aaa.m=myabs(aaa.m);
						else
							aaa.m=aaa.m*(-1);
						aaa.x=px[j]+aaa.m;
						aaa.ymin=py[j+1];
						aaa.next=NULL;
						struct active_edge_table *p;
						if(NET[y-1]==NULL)
						{
							NET[y-1]=new struct active_edge_table;
							NET[y-1]->m=aaa.m;
							NET[y-1]->x=aaa.x;
							NET[y-1]->ymin=aaa.ymin;
							NET[y-1]->next=NULL;
						}
						else
						{
							p=NET[y-1];
							while(p->next!=NULL)
							{
								p=p->next;
							}
							p->next=new struct active_edge_table;
							struct active_edge_table *q;
							q=p->next;
							q->m=aaa.m;
							q->x=aaa.x;
							q->ymin=aaa.ymin;
							q->next=NULL;
						}
						continue;
					}

				}

				if(py[j+1]<py[j]&&py[j-1]<py[j])
				{
					struct active_edge_table aa1;
					struct active_edge_table bb1;
					aa1.m=float(px[j+1]-px[j])/(py[j+1]-py[j]);
					aa1.m=myabs(aa1.m);
					if(px[j+1]>px[j])
						aa1.m=myabs(aa1.m);
					else
						aa1.m=aa1.m*(-1);
					aa1.x=px[j]+aa1.m;
					aa1.ymin=py[j+1];
					bb1.m=float(px[j-1]-px[j])/(py[j-1]-py[j]);
					bb1.m=myabs(bb1.m);
					if(px[j-1]>px[j])
						bb1.m=myabs(bb1.m);
					else
						bb1.m=bb1.m*(-1);
					bb1.x=px[j]+bb1.m;
					bb1.ymin=py[j-1];
					bb1.next=NULL;
					struct active_edge_table *p;
					if(NET[y-1]==NULL)
					{
						NET[y-1]=new struct active_edge_table;
						NET[y-1]->m=aa1.m;
						NET[y-1]->x=aa1.x;
						NET[y-1]->ymin=aa1.ymin;
						NET[y-1]->next=new struct active_edge_table;
						NET[y-1]->next->m=bb1.m;
						NET[y-1]->next->ymin=bb1.ymin;
						NET[y-1]->next->x=bb1.x;
						NET[y-1]->next->next=bb1.next;
					}
					else
					{
						p=NET[y-1];
						while(p->next!=NULL)
						{
							p=p->next;
						}
						p->next=new struct active_edge_table;
						struct active_edge_table *q;
						q=p->next;
						q->m=aa1.m;
						q->x=aa1.x;
						q->ymin=aa1.ymin;
						q->next=new struct active_edge_table;
						q->next->m=bb1.m;
						q->next->ymin=bb1.ymin;
						q->next->x=bb1.x;
						q->next->next=bb1.next;

					}
					continue;
				}

				if(py[j+1]>py[j]&&py[j-1]>py[j])
					continue;
				if(py[j+1]>py[j]&&py[j-1]<py[j])
				{
					struct active_edge_table bb2;
					bb2.m=float(px[j-1]-px[j])/(py[j-1]-py[j]);
					bb2.m=myabs(bb2.m);
					if(px[j-1]>px[j])
						bb2.m=myabs(bb2.m);
					else
						bb2.m=bb2.m*(-1);
					bb2.x=px[j]+bb2.m;
					bb2.ymin=py[j-1];
					bb2.next=NULL;
					struct active_edge_table *p;
					if(NET[y-1]==NULL)
					{
						NET[y-1]=new struct active_edge_table;
						NET[y-1]->m=bb2.m;
						NET[y-1]->x=bb2.x;
						NET[y-1]->ymin=bb2.ymin;
						NET[y-1]->next=bb2.next;
					}
					else
					{
						p=NET[y-1];
						while(p->next!=NULL)
						{
							p=p->next;
						}
						p->next=new struct active_edge_table;
						struct active_edge_table *q;
						q=p->next;
						q->m=bb2.m;
						q->x=bb2.x;
						q->ymin=bb2.ymin;
						q->next=NULL;
					}
					continue;
				}
				if(py[j+1]<py[j]&&py[j-1]>py[j])
				{
					struct active_edge_table aa2;
					aa2.m=float(px[j+1]-px[j])/(py[j+1]-py[j]);
					aa2.m=myabs(aa2.m);
					if(px[j+1]>px[j])
						aa2.m=myabs(aa2.m);
					else
						aa2.m=aa2.m*(-1);
					aa2.x=px[j]+aa2.m;
					aa2.ymin=py[j+1];
					aa2.next=NULL;
					struct active_edge_table *p;
					if(NET[y-1]==NULL)
					{
						NET[y-1]=new struct active_edge_table;
						NET[y-1]->m=aa2.m;
						NET[y-1]->x=aa2.x;
						NET[y-1]->ymin=aa2.ymin;
						NET[y-1]->next=aa2.next;
					}
					else
					{
						p=NET[y-1];
						while(p->next!=NULL)
						{
							p=p->next;
						}
						p->next=new struct active_edge_table;
						struct active_edge_table *q;
						q=p->next;
						q->m=aa2.m;
						q->x=aa2.x;
						q->ymin=aa2.ymin;
						q->next=NULL;
					}
					continue;
				}
				if(py[j+1]==py[j]&&py[j-1]<py[j])
				{
					struct active_edge_table aaa;
					aaa.m=float(px[j-1]-px[j])/(py[j-1]-py[j]);
					aaa.m=myabs(aaa.m);
					if(px[j-1]>px[j])
						aaa.m=myabs(aaa.m);
					else
						aaa.m=aaa.m*(-1);
					aaa.x=px[j]+aaa.m;
					aaa.ymin=py[j-1];
					aaa.next=NULL;
					struct active_edge_table *p;
					if(NET[y-1]==NULL)
					{
						NET[y-1]=new struct active_edge_table;
						NET[y-1]->m=aaa.m;
						NET[y-1]->x=aaa.x;
						NET[y-1]->ymin=aaa.ymin;
						NET[y-1]->next=NULL;
					}
					else
					{
						p=NET[y-1];
						while(p->next!=NULL)
						{
							p=p->next;
						}
						p->next=new struct active_edge_table;
						struct active_edge_table *q;
						q=p->next;
						q->m=aaa.m;
						q->x=aaa.x;
						q->ymin=aaa.ymin;
						q->next=NULL;
					}
					continue;
				}
				if(py[j+1]<py[j]&&py[j-1]==py[j])
				{
					struct active_edge_table aaa;
					aaa.m=float(px[j+1]-px[j])/(py[j+1]-py[j]);
					aaa.m=myabs(aaa.m);
					if(px[j+1]>px[j])
						aaa.m=myabs(aaa.m);
					else
						aaa.m=aaa.m*(-1);
					aaa.x=px[j]+aaa.m;
					aaa.ymin=py[j+1];
					aaa.next=NULL;
					struct active_edge_table *p;
					if(NET[y-1]==NULL)
					{
						NET[y-1]=new struct active_edge_table;
						NET[y-1]->m=aaa.m;
						NET[y-1]->x=aaa.x;
						NET[y-1]->ymin=aaa.ymin;
						NET[y-1]->next=NULL;
					}
					else
					{
						p=NET[y-1];
						while(p->next!=NULL)
						{
							p=p->next;
						}
						p->next=new struct active_edge_table;
						struct active_edge_table *q;
						q=p->next;
						q->m=aaa.m;
						q->x=aaa.x;
						q->ymin=aaa.ymin;
						q->next=NULL;
					}
					continue;
				}
			}
	}
}
//在活化链表中插入一个结点,并排序
struct active_edge_table *insert_node(struct active_edge_table *head, struct active_edge_table *stud)
{
	struct active_edge_table *p0,*p1,*p2,*p3;
	p1=head;
	p0=stud;
	if(head==NULL)
	{ //活化链表为空
		p0->next=NULL;
		head=p0;
	}
	else
	{ //寻找插入位置
		while((p0->x>p1->x)&&(p1->next!=NULL))
		{
			p2=p1;
			p1=p1->next;
		}
		if(p0->x<p1->x)
		{ //当x坐标不等时,按x递增插入排序
			if(head==p1)
			{ //插入在第一结点之前
				p0->next=p1;
				head=p0;
			}
			else
			{ //非尾结点插入
				p2->next=p0;
				p0->next=p1;
			}
		}
		else if(p0->x==p1->x)
		{ //当x坐标相等时,可能遇到两条线段有相同的x坐标,按m递增插入排序
			if(p0->m < p1->m)
			{
				p2->next=p0;
				p0->next=p1;
			}
			else
			{
				p3=p1->next;
				p1->next=p0;
				p0->next=p3;
			}
		}
		else
		{
			p0->next=NULL; //结点插到表尾
			p1->next=p0;
		}
	}
	return(head);
}
//从活化边表中删除一个结点
struct active_edge_table * del_node(struct active_edge_table * head,int ys)
{
	struct active_edge_table *p1,*p2=NULL;
	p1=head;
	do
	{
		if(ys==p1->ymin)
		{
			if(p1==head)
			{
				head=p1->next; p1=p1->next;
			}
			else
			{
				p2->next=p1->next;
				p1=p2->next;
			}
		}
		else
		{
			p2=p1;
			p1=p1->next;
		}
	}
	while(p1!=NULL);
	return(head);
}
void init(void)
{
	glClearColor (1.0, 1.0, 1.0, 0.0);
	glClear (GL_COLOR_BUFFER_BIT);
	glClear (GL_COLOR_BUFFER_BIT);
}

void polyScanFill (void)
{
	int i,ymin,ymax;
	struct active_edge_table *p=NULL,*q=NULL,*aet_head=NULL;
	//	int px[M]={100,100,240,380,460,300,200,100};
	//	int py[M]={140,240,160,260,120, 80, 80,140};
	//	int px[M]={100,100,240,380,400,460,300,100};
	//	int py[M]={140,240,160,260,120,120, 80,140};
//	int px[M]={100,100,200,200,300,250,130,100};
//	int py[M]={140,240,240,140,100,80, 80,140};
	int px[M]={100,100,200,200,300,250,130,100};
	int py[M]={140,240,240,140,140,80, 80,140};
	ymin=y_min(py);
	ymax=y_max(py);
	int Min=ymin;
	int Max=ymax;
	for(i=ymin;i<=maxy;i++)
		NET[i]=NULL; //将新边表数组初始化为空指针
	polyNet(px, py);
	for(i=ymax;i>=ymin;i--)
	{ //逐条扫描线填充
		if(NET[i]!=NULL)
		{ //如果有新边加入,插入活化边表,并排序
			p=NET[i]; q=p;
			while(q)
			{
				q=p->next;
				aet_head=insert_node(aet_head,p);
				p=q;
			}
		}
		if(aet_head!=NULL)
		{ //对活化边表线段进行填充
			glColor3f (0.0, 0.0, 1.0);
			p=aet_head;
			q=p->next;
			glBegin(GL_LINES);
			glVertex2i(ROUND(p->x),i);
			glVertex2i(ROUND(q->x),i);
			glEnd();
			while((q->next)!=NULL)
			{
				p=q->next;
				q=p->next;
				glBegin(GL_LINES);
				glVertex2i(ROUND(p->x),i);
				glVertex2i(ROUND(q->x),i);
				glEnd();
			}
			aet_head=del_node(aet_head,i);
			p=aet_head;
			while(p)
			{
				p->x=p->x+p->m;
				p=p->next;
			}
			//	Sleep(10);
		} //if(aet_head)
	}
	glColor3f (1.0, 0.0, 0.0);
	glLineWidth(2.0);
	glBegin(GL_LINE_LOOP);
	for(i=0;i<M-1;i++){
		glVertex2i(px[i],py[i]);
	}
	glEnd();
	glFlush ( );
}
void winReshapeFcn (int newWidth, int newHeight)
{
	glMatrixMode (GL_PROJECTION);
	glLoadIdentity ( );
	gluOrtho2D (0.0, (GLdouble) newWidth, 0.0, (GLdouble) newHeight);
}
int main(int argc, char** argv)
{
	glutInit (&argc, argv);
	glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
	glutInitWindowPosition (100, 100);
	glutInitWindowSize (winWidth, winHeight);
	glutCreateWindow ("PROGRAM");
	init();
	glutReshapeFunc (winReshapeFcn);
	glutDisplayFunc (polyScanFill);
	glutMainLoop ( );
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值