Xén hình C++

hinh1 hinh2

hinh3

hinh4

hinh5

hinh6

Sau xin hiện thực thuật toán bằng code C++


#include "stdafx.h"
#include "glut.h"
#include 
#include 
#include 
int tempx1,tempy1,tempx2,tempy2;
#define ve 1
#define xen 2
#define xenli 3
int screenWidth=640;
int screenHeight=640;
typedef struct
{ 
	GLfloat x1,y1;
	GLfloat x2,y2;
} GLintPoint;
#define NUM 100
GLintPoint list[NUM];
int last=-1;
GLfloat x,y,xt1,xt2,yt1,yt2;
typedef struct  
{
	GLfloat top;
	GLfloat bottom;
	GLfloat left;
	GLfloat right;
}bit;


void hoanvi(GLfloat &x,GLfloat &y)
{
	GLfloat tam;
	tam=x;
	x=y;
	y=tam;
}
// ham doan thang bang bresenham, input 2 toa do cau 2 dau doan thang
void BRE(GLfloat x1,GLfloat y1,GLfloat x2,GLfloat y2)
{
	
	GLfloat x,y,dx,dy,p;
	if(x1>x2)
	{
		hoanvi(x1,x2);
	 	hoanvi(y1,y2);
	}
	glColor3f(0.0f, 1.4f, 1.0f);
		 glBegin(GL_POINTS);
			glVertex2i(x1,y1); 
	dx=abs(x2-x1);
	dy=abs(y2-y1);
	x=x1;
	y=y1;
	float const1y=2*dy;
	float const1x=2*dx;
	float const2y=2*(dy-dx);
	float const2x=2*(dx-dy);
	if(dx>dy)
	{
		p=2*dy-dx;
		glVertex2i(x,y); 
		while(x<=x2)
		{
			
			if(p<0)
				p+=const1y;
			else
			{     
				if(y1else
				{
					
					p+=const2y;
					y--;
				}
			}
			x++;
			glVertex2i(x,y); 
		}
	}
	else
	{
		p=2*dx-dy;
		glVertex2i(x,y); 
		if(y1while(y<=y2)
			{
				
				if(p<0)
					p+=const1x;
				else
				{
					
					p+=const2x;
					x++;
				}
				y++;
				glVertex2i(x,y); 
			}
		}
		else
		{
			while(y>=y2)
			{
				
				if(p<0)
					p+=const1x;
				else
				{
					
					p+=const2x;
					x++;
				}
				y--;
				glVertex2i(x,y); 
			}
		}
	}
}
//ham tinh diem do o vi tri nao so voi khung cat,input toa do de xet,output bit da dc xet
bit tinh(GLfloat x,GLfloat y,bit w)
{
	//printf("%d %d %d",x,y,w.top); 
	bit c;
	c.bottom=0;
	c.left=0;
	c.right=0;
	c.top=0;
	if(y1;
	else if(y>w.top)
		c.top=1;
	if(x1;
		else if(x>w.right) 
		c.right=1;
	//printf("l=%f r=%f b=%f t=%f\n",c.left,c.right,c.bottom,c.top);
	return c;
}
// ham xet truong 2 diem nam nhung the nao so khung cat
//1 tu la doan thang nam trong hoan toan,2 doan thang nam ngoai hoan toan,3 truong hop con lai
int xettruonghop(bit c1,bit c2)
{
	//printf("%d %d",c1.left,c2.left);
	if(c1.bottom==0&&c1.left==0&&c1.right==0&&c1.top==0&&c2.bottom==0&&c2.left==0&&c2.right==0&&c2.top==0)
		return 1;
	else if(((c1.left==c2.left)&&c1.left==1)||((c1.bottom==c2.bottom)&&c1.bottom==1)||((c1.right==c2.right)&&c1.right==1)||((c1.top==c2.top)&&c1.top==1))
			return 2;
	
		return 3;
}
void output();
void output1();
//ham lay toa do da dc xen
void Xen(GLfloat x1,GLfloat y1,GLfloat x2,GLfloat y2)
{
	bit c1,c2,w;
	int th;
	if(x1>x2)
	{
		
		w.left=x2;
		w.right=x1;
	}
	else if(x1<=x2)
		{
		
		w.left=x1;
		w.right=x2;
		}
	if(y1>y2)
	{
		w.bottom=y2;
		w.top=y1;
	}
	
	else if(y1<=y2)
	{
		w.bottom=y1;
		w.top=y2;	
	}	
	//printf("%f\t%f\t%f\t%f\n", w.left, w.right, w.bottom, w.top);
for(int i=0;i <=last;i++)
{
	c1=tinh(list[i].x1,list[i].y1,w);
	c2=tinh(list[i].x2,list[i].y2,w);
	float dx=list[i].x2-list[i].x1;
	float dy=list[i].y2-list[i].y1;
	th=xettruonghop(c1,c2);
	//printf("l=%f r=%f b=%f t=%f\n",c1.left,c1.right,c1.bottom,c1.top);
	//printf("l=%f r=%f b=%f t=%f\n\n",c2.left,c2.right,c2.bottom,c2.top);
	if(th==1)
		continue;
	if(th==2)
	{
		
		list[i].x1=0;
		list[i].x2=0;
		list[i].y1=0;
		list[i].y2=0;
	}
	
	if(th==3)
	
		//while(th==3)
		do
		{
			//printf("Truong hop 3\n");
			if(c1.left==1)
			{
				float temp=list[i].y1;
				list[i].y1=temp+((dy/dx)*(w.left-list[i].x1));
				list[i].x1=w.left;
			}
			if(c1.right==1)
				{
					float temp=list[i].y1;
					list[i].y1=temp+((dy/dx)*(w.right-list[i].x1));
					list[i].x1=w.right;
				}
			if(c1.bottom==1)
			{
				float temp=list[i].x1;
				list[i].x1=temp+(dx/dy)*(w.bottom-list[i].y1);
				list[i].y1=w.bottom;
			}
			
			if(c1.top==1)
				{
				float temp=list[i].x1;
				list[i].x1=temp+(dx/dy)*(w.top-list[i].y1);
				list[i].y1=w.top;
			}
			c1=tinh(list[i].x1,list[i].y1,w);
			if(c2.left==1)
			{
				float temp=list[i].y2;
				list[i].y2=temp+((dy/dx)*(w.left-list[i].x2));
				list[i].x2=w.left;
			}
			if(c2.right==1)
				{
					float temp=list[i].y2;
					list[i].y2=temp+((dy/dx)*(w.right-list[i].x2));
					list[i].x2=w.right;
				}
			if(c2.bottom==1)
			{
				float temp=list[i].x2;
				list[i].x2=temp+(dx/dy)*(w.bottom-list[i].y2);
				list[i].y2=w.bottom;
			}
			
			if(c2.top==1)
				{
				float temp=list[i].x2;
				list[i].x2=temp+(dx/dy)*(w.top-list[i].y2);
				list[i].y2=w.top;
			}
			c2=tinh(list[i].x2,list[i].y2,w);
			th=xettruonghop(c1,c2);
			
		}
		while(th==3);
	}

	output();
	
}

//dung thuat toan Liangbasky den xen doan thang,input la 2 diem cua doan thang,output 2 diem da dc xen
void LiangBasky(GLintPoint &list,float x1,float y1,float x2,float y2)
{
	float xmin,xmax,ymin,ymax;
	if(x1>x2)
	{
		xmin=x2;
		xmax=x1;
	}
	else
	{
		xmin=x1;
		xmax=x2;
	}
	if(y1>y2)
	{
		
		ymin=y2;
		ymax=y1;
	}
	else
	{
		ymin=y1;
		ymax=y2;
	}
	//printf("%f %f",xmin,xmax);
	

  // Khởi tạo các giá trị Pi, Qi

  float P[4], Q[4];
	float dx,dy;
	dx=(float)list.x2-list.x1;
	dy=(float)list.y2-list.y1;
  P[0] = -dx; Q[0] = (float)list.x1-xmin;

  P[1] = dx; Q[1] = (float)xmax-list.x1;

  P[2] =-dy; Q[2] = (float)list.y1-ymin;

  P[3] =dy;  Q[3] = (float)ymax-list.y1;

 

  // Xuất phát với giá trị tmin=0 (đầu 0), tmax=1 (đầu 1)

  double tk, tmin=0, tmax=1;
  // Lần lượt giải từng bất phương trình trong hệ 4 bất phương trình

  for (int k=0; k<=3; k++) {

    if (P[k]==0) 
	{

      if (Q[k]<0) return;       // Bất phương trình vô nghiệm, đoạn thẳng ko cắt

    } else 
	{
		
      tk =(double)(Q[k])/P[k];   // Nghiệm của bất phương trinh
		
      if (P[k]>0) 
	  {
		if (tmax>tk)
		{
			tmax = tk; // Pk>0, nghiệm dạng t<tk -> cận trên
			printf("%f\n",tmax);
		}
	}
	  else 
	  {

        if (tmin// Pk<0, nghiệm dạng t>tk -> cận dưới

      }

    }

  }

	
  // Nếu tmin>tmax, đoạn thẳng không cắt vùng nhìn

  if (tmin<=tmax) 
  {
	
    // Xác định phần đoạn thẳng cắt vùng nhìn bằng cách thay tmin, tmax

    list.x1=(list.x2-list.x1)*tmin+list.x1;
	list.y1=(list.y2-list.y1)*tmin+list.y1;

	list.x2=((list.x2-list.x1)*tmax+list.x1);
	list.y2=((list.y2-list.y1)*tmax+list.y1);

  }
  else
	 {

    // Xác định phần đoạn thẳng cắt vùng nhìn bằng cách thay tmin, tmax

    list.x1=0;
	list.y1=0;

	list.x2=0;
	list.y2=0;

  }
	
}
//ham xu ly tat ca doan thang voi input la toa do gioi han
void Xen1(GLfloat x1,GLfloat y1,GLfloat x2,GLfloat y2)
{
	
for(int i=0;i <=last;i++)
{
	
	LiangBasky(list[i], x1, y1, x2, y2);
}

	output();
	
}
//xuat doan thang
void output()
{
	
	glClear(GL_COLOR_BUFFER_BIT);
	for(int i=0;i <=last;i++)
	{
		BRE(list[i].x1,list[i].y1,list[i].x2,list[i].y2);
		glClear(GL_COLOR_BUFFER_BIT);
		
	}
		//BRE(xt1,yt1,xt2,yt2);
		glClear(GL_COLOR_BUFFER_BIT);
	glEnd();
	glutSwapBuffers();
}
//xuat doan thang
void output1()
{
	
	glClear(GL_COLOR_BUFFER_BIT);
	for(int i=0;i <=last;i++)
	{
		BRE(list[i].x1,list[i].y1,list[i].x2,list[i].y2);
		glClear(GL_COLOR_BUFFER_BIT);
		
	}
		BRE(xt1,yt1,xt2,yt2);
		glClear(GL_COLOR_BUFFER_BIT);
	glEnd();
	glutSwapBuffers();
}
//lay toa do chuot de ve doan thang

void xulychuot(int button,int status,int x,int y)
{
	if(button==0&&status==0)
	{
		xt1=x;
		yt1=screenHeight-y;
	}
	if(button==0&&status==1)
	{
		xt2=x;
		yt2=screenHeight-y;
		BRE(xt1,yt1,xt2,yt2);
		last++;
		list[last].x1=xt1;
		list[last].y1=yt1;
		list[last].x2=xt2;
		list[last].y2=yt2;
		output();
	}
	
}
void chuotdichuyen(int x,int y)
{
	glClear(GL_COLOR_BUFFER_BIT);
	xt2 = x;
	yt2 = screenHeight-y;
	output1();
}
void SetupRC()
{
	glClearColor(0,0,0,0);
	glClear(GL_COLOR_BUFFER_BIT);
	glPointSize(1.0);
	gluOrtho2D(0,screenWidth,0,screenHeight);
}
//ve hinh vuong bang doan thang,voi input luc lick chuot
void hinh_vuong(GLfloat x1,GLfloat y1,GLfloat x2,GLfloat y2)
{
	glClear(GL_COLOR_BUFFER_BIT);
	BRE(x1,y1,x2,y1);
	BRE(x2,y1,x2,y2);
	BRE(x2,y2,x1,y2);
	BRE(x1,y2,x1,y1);
	Xen(x1,y1,x2,y2);
}
void chuotdichuyenxen(int x,int y)
{
	GLfloat x2,y2;
	glClear(GL_COLOR_BUFFER_BIT);
	x2 = x;
	y2 = screenHeight-y;

	BRE(tempx1,tempy1,x2,tempy1);
	BRE(x2,tempy1,x2,y2);
	BRE(x2,y2,tempx1,y2);
	BRE(tempx1,y2,tempx1,tempy1);
	output();
	glEnd();
	glutSwapBuffers();
}
void xulyxen(int button,int status,int x,int y)
{
	
	if(button==0&&status==0)
	{
		tempx1=x;
		tempy1=screenHeight-y;
	}
	if(button==0&&status==1)
	{
		tempx2=x;
		tempy2=screenHeight-y;
		hinh_vuong(tempx1,tempy1,tempx2,tempy2);
	}
	
}
void chuotdichuyenxen1(int x,int y)
{
	GLfloat x2,y2;
	glClear(GL_COLOR_BUFFER_BIT);
	x2 = x;
	y2 = screenHeight-y;

	BRE(tempx1,tempy1,x2,tempy1);
	BRE(x2,tempy1,x2,y2);
	BRE(x2,y2,tempx1,y2);
	BRE(tempx1,y2,tempx1,tempy1);
	output();
	glEnd();
	glutSwapBuffers();
}
void hinh_vuong1(GLfloat x1,GLfloat y1,GLfloat x2,GLfloat y2)
{
	glClear(GL_COLOR_BUFFER_BIT);
	BRE(x1,y1,x2,y1);
	BRE(x2,y1,x2,y2);
	BRE(x2,y2,x1,y2);
	BRE(x1,y2,x1,y1);
	Xen1(x1,y1,x2,y2);
}
void xulyxen1(int button,int status,int x,int y)
{
	
	if(button==0&&status==0)
	{
		tempx1=x;
		tempy1=screenHeight-y;
	}
	if(button==0&&status==1)
	{
		tempx2=x;
		tempy2=screenHeight-y;
		hinh_vuong1(tempx1,tempy1,tempx2,tempy2);
	}
	
}
void processMenuEvents(int option) 
{

	switch (option)
	{
		
		
				
		case ve :
			glutMouseFunc(xulychuot);
			glutMotionFunc(chuotdichuyen);
			glutDisplayFunc(output);
	
		
				break;
		case xen:
				glutMouseFunc(xulyxen);
				glutMotionFunc(chuotdichuyenxen);
				glutDisplayFunc(output);
				break;
	case xenli:
				glutMouseFunc(xulyxen1);
				glutMotionFunc(chuotdichuyenxen1);
				glutDisplayFunc(output);
				break;
	

	}
}
void createGLUTMenus()
{

	int submenu;
	submenu = glutCreateMenu(processMenuEvents);
	glutAddMenuEntry("Ve duong thang",ve);
	glutAddMenuEntry("Xen Anh Cohen",xen);
	glutAddMenuEntry("Xen Anh LiangBasky",xenli);
	glutAttachMenu(GLUT_RIGHT_BUTTON);
}
int _tmain(int argc, char* argv[])
{
	glutInit(&argc,argv);
	glutInitDisplayMode(GLUT_DOUBLE);
	glutInitWindowSize(screenWidth,screenHeight);
	glutCreateWindow("ve duong thang thuat toan Bresenham");
	SetupRC();
	createGLUTMenus();
	glutDisplayFunc(output);
	
	glutMainLoop();
	return 0;
}

Chủ đề liên quan
Xén hình C++

Cùng chuyên mục

Xem nhiều hôm nay