本部落格電腦圖形學系列文章索引:
地址:《電腦圖形學系列相關文章索引(持續更新)》
參考教材:《電腦圖形學》 機械工業出版社 ,徐文鵬主編
實驗內容:利用Cohen-Sutherland編碼裁剪演算法,用矩形框裁剪直線。
實驗代碼如下(已調試過):
#include <GL/glut.h>#include <stdio.h>#include <stdlib.h>#pragma comment( lib, "opengl32.lib" ) #pragma comment( lib, "glu32.lib" ) #pragma comment( lib, "glut32.lib" ) #define LEFT_EDGE 1#define RIGHT_EDGE 2#define BOTTOM_EDGE 4#define TOP_EDGE 8static int times=1;//畫從(x0,y0)到(x1,y1)的直線void LineGL(int x0,int y0,int x1,int y1){glBegin(GL_LINES);glColor3f(1.0f,0.0f,0.0f);glVertex2f(x0,y0);glColor3f(0.0f,1.0f,0.0f);glVertex2f(x1,y1);glEnd();}//矩形的結構體typedef struct Rectangle{float xmin;float xmax;float ymin;float ymax;} Rectan;Rectan rect;int x0,y0,x1,y1;//求出座標點的Cohen-Sutherland編碼int CompCode(int x,int y,Rectan rect){int code = 0x00;if (y < rect.ymin){code=code | 4;}if (y>rect.ymax){code = code | 8;}if (x>rect.xmax){code= code | 2;}if (x<rect.xmin){code=code | 1;}return code;}//裁剪直線int cohensutherlandlineclip(Rectan rect,int& x0,int& y0,int& x1,int& y1){int accept=0,done=0;float x,y;int code0,code1,codeout;int x00 = x0,y00 = y0,x11 = x1,y11 = y1;code0= CompCode(x0,y0,rect);code1= CompCode(x1,y1,rect);//直線全部在矩形框內部,應保留if (!(code0 | code1)){accept=1;done=1;} //直線和矩形不相交,並且劃直線的兩點在矩形同側(上、下、右。左),應去掉。if( code0 & code1 ){done=1;}while(!done){//直線和矩形有交點,只保留矩形內部的if (!(code0 | code1)){accept=1;done=1;} else{if (code0 != 0){codeout =code0;} else{codeout =code1;}if (codeout & LEFT_EDGE){y=y0+(y1-y0)*(rect.xmin-x0)/(x1-x0);x=(float)rect.xmin;} else{if (codeout &RIGHT_EDGE){y=y0+(y1-y0)*(rect.xmax-x0)/(x1-x0);x=(float)rect.xmax;} else{if (codeout & BOTTOM_EDGE){x=y0+(x1-x0)*(rect.ymin-y0)/(y1-y0);y=(float)rect.ymin;} else{if (codeout & TOP_EDGE){x=x0+(x1-x0)*(rect.ymax-y0)/(y1-y0);y=(float)rect.ymax;}}}}if (codeout == code0){x0=x;y0=y;code0=CompCode(x0,y0,rect);} else{x1=x;y1=y;code1=CompCode(x1,y1,rect);}//直線和矩形不相交,但是劃直線的兩點在矩形不同側,這時應去掉。if((times<=3) && (code0 & code1)){x0=x1;y0=y1;done=1;accept=1;}}}if (accept){LineGL(x0,y0,x1,y1);}return accept;}void myDisplay(){glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0f,0.0f,0.0f);glRectf(rect.xmin,rect.ymin,rect.xmax,rect.ymax);LineGL(x0,y0,x1,y1);glFlush();}void Init(){glClearColor(0.0,0.0,0.0,0.0);glShadeModel(GL_FLAT);rect.xmin =100;rect.xmax =300;rect.ymin=100;rect.ymax=300;x0=0;y0=650;x1=650;y1=0;}void Reshape(int w,int h){glViewport(0,0,(GLsizei)w,(GLsizei)h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0,(GLdouble)w,0.0,(GLdouble)h);}//按鍵盤上字母c裁剪,字母r恢複原狀,字母x退出。void keyboard(unsigned char key,int x,int y){switch(key){case 'c':cohensutherlandlineclip(rect,x0,y0,x1,y1);glutPostRedisplay();break;case 'r':Init();glutPostRedisplay();break;case 'x':exit(0);break;default:break;}}int main(int argc,char* argv[]){glutInit(&argc,argv);glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);glutInitWindowPosition(100,100);glutInitWindowSize(640,480);glutCreateWindow("裁剪");Init();glutDisplayFunc(myDisplay);glutReshapeFunc(Reshape);glutKeyboardFunc(keyboard);glutMainLoop();return 0;}
實驗結果(修改不同的(x0,y0)和(x1,y1)可得到):