#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; }