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

📄 huyingfei.cpp

📁 这是用java编写的一个简单的计算器的源码以及编译后生成的文件
💻 CPP
字号:
#include <windows.h>
#include <gl/gl.h>
#include <gl/glaux.h>
#include <gl/glu.h>
#include <iostream.h>
#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->xInt<p->xInt)//测试活化边表按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<yComp)
		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<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;
	}
}
void deleteEdge(Edge *q)//删除扫描过的边
{
	Edge *p=q->next;
	q->next=p->next;
	free(p);
}
void sort(Edge *list,Edge *edge)//对活化边表中的边进行排序
{
	Edge *p,*q=list;
	p=q->next;//p指向y=lower.y的第一条边
	while(p!=NULL)
	{
		if(edge->E_mark<p->E_mark)//首先按多边形类型进行排序,第一个排在最前面
		{
				p=NULL;
		}
		else if(edge->E_mark==p->E_mark)	//接着按具体某一个多边形的边的x值进行排序
			{
				if(edge->xInt<p->xInt)//测试活化边表按x增加排序,从而保证了扫描时从左往右的准确性
					p=NULL;
				else
				{
					q=p;          //p、q后移
					p=p->next;
				}
			}
			else	
			{
				q=p;	    //p、q后移
				p=p->next;
			}
	}
	edge->next=q->next;//插入edge边
	q->next=edge;
}
void getActiveList(int scan,Edge *active,Edge *edges[])//构造活化边表
{
	Edge *p,*q;
	p=edges[scan]->next;//p指向edges[scan]的第一条边
	while(p)
	{
		q=p->next;//q指向下一条边
		sort(active,p);
		p=q;
	}
}
void scanfill()
{
	Edge **edges=new Edge* [SCAN_NUM];       //边Y桶
	Edge *active;								//边活化边表
	int i,yscan,j;
	for(i=0;i<SCAN_NUM;i++)
	{
		edges[i]=new Edge;//初始化有序边表
		edges[i]->next=NULL;
	}
	for(i=0;i<num;i++)
		getEdgeList(counts[i],points[i],edges,i);//修改边Y桶
	active=new Edge;
	active->next=NULL;

	int  FraBuffer[SCAN_NUM][SCAN_NUM]; //创建桢缓冲器和Z缓冲器
	int  ZBuffer[SCAN_NUM];
	for(i=0;i<SCAN_NUM;i++)
	{
		ZBuffer[i]=-10000;
		for(j=0;j<SCAN_NUM;j++)    
			FraBuffer[i][j]=-1;
	}
		for(yscan=0;yscan<SCAN_NUM;yscan++)
	{
		getActiveList(yscan,active,edges);//构造好活化边表
		if(active->next)
		{
			Edge *q=active,*p=active->next;
			while(p)                      //遍历一趟活化边表,一次两条边,即找到一个顶点对
			{
				q=p->next;
				for(int xx=p->xInt;xx<=q->xInt;xx++)//比较当前顶点对之间
				{
					int zz;							//点的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->next;				
			}
			for(i=0;i<SCAN_NUM;i++)				//当前扫描线对应的桢缓冲器中的颜色值
			{
				if(FraBuffer[yscan][i]==0)			//显示输出,假设本程序最多有8个多边形
				{
					::glColor3f(1.0, 0.0, 0.0);
					DrawPoint(i,yscan);
				}
				else if(FraBuffer[yscan][i]==1)
				{
					::glColor3f(1.0, 1.0, 0.0);
					DrawPoint(i,yscan);
				}
				else if(FraBuffer[yscan][i]==2)
				{
					::glColor3f(1.0, 0.0, 1.0);
					DrawPoint(i,yscan);
				}
				else if(FraBuffer[yscan][i]==3)
				{
					::glColor3f(0.0, 0.1, 0.2);
					DrawPoint(i,yscan);
				}
				else if(FraBuffer[yscan][i]==4)
				{
					::glColor3f(0.2, 0.1, 0.0);
					DrawPoint(i,yscan);
				}
				else if(FraBuffer[yscan][i]==5)
				{
					::glColor3f(0.1, 0.2, 0.0);
					DrawPoint(i,yscan);
				}
				else if(FraBuffer[yscan][i]==6)
				{
					::glColor3f(0.1, 0.2, 0.2);
					DrawPoint(i,yscan);
				}
				else if(FraBuffer[yscan][i]==7)
				{
					::glColor3f(0.4, 0.6, 0.3);
					DrawPoint(i,yscan);
				}

				ZBuffer[i]=-1000;					//恢复Z缓冲器中的值,以备下次扫描时使用
			}
			//更新活化边表中具体的边中的元素值
			q=active;
			p=active->next;//更新具体每条边的值或者删除某些边
			while(p)
			{
				if(yscan>=p->yUpper)//当扫描线即将于某一条边分离时,删除此边
				{
					p=p->next;//p后移
					deleteEdge(q);
				}
				else
				{
					p->xInt=p->xInt+p->dx;//扫描线仍与此边相交,更新下一次扫描时的x坐标的值
					p->z+=(p->dzx*p->dx+p->dzy);
					q=p;					//p、q后移
					p=p->next;
				}
			}
			//更新活化边表,对更新后的边进行重新排序
			p=active->next;//更新活化边表
			active->next=NULL;
			while(p)
			{
				q=p->next;
				sort(active,p); //调用排序函数,此函数乃是本算法的关键所在
				p=q;
			}
		}
	}
}
void CALLBACK Reshape(GLsizei w, GLsizei h)
{
	::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;
}
void CALLBACK Display1()
{
scanfill();
::glFlush();
return;
}
void Init()
{
	::auxInitDisplayMode(AUX_RGBA|AUX_SINGLE);
	::auxInitPosition(0, 0, 500, 500);
	::auxInitWindow("Scan algithmic");

	::glShadeModel(GL_FLAT);
	::glClearColor(0.0, 0.0, 0.0, 0.0);
}
void main(int argc, char **argv)
{
	int x,y,z;
	float a,b,c,d;
	int n;
	cout<<"下面将一个复杂的空间图形按照其具有的平面进行输入"<<endl<<endl;
	cout<<"请输入多边形个数:"<<endl;
	cin>>num;
	points=new point*[num];
	as=new float*[num];
	counts=new int[num];
	for(int i=0;i<num;i++)
	{
		cout<<"请输入第"<<i<<"个多边形的顶点个数"<<endl;
		cin>>n;
		counts[i]=n;
		points[i]=new point[n];
		for(int j=0;j<n;j++)
		{
			cin>>x>>y>>z;
			points[i][j].x=x;
			points[i][j].y=y;
			points[i][j].z=z;
		}
		as[i]=new float[4];
		cout<<endl<<"请输入第"<<i<<"个多边形的四个系数:"<<endl;
		cin>>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);
	return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -