要求:利用编码裁剪(Cohen-Sutherland)法裁剪《计算机图形学基础》(第二版)(p183 图6-40)所示线段。
#include<GL/glut.h> #include<stdio.h> #include<stdlib.h> #define LEFT_EDGE 1 #define RIGHT_EDGE 2 #define BOTTOM_EDGE 4 #define TOP_EDGE 8 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(); } struct Rectangle { float xmin,xmax,ymin,ymax; }; Rectangle rect; int x0,y0,x1,y1; int CompCode(int x,int y,Rectangle 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(Rectangle rect,int &x0,int &y0,int &x1,int &y1) { int accept,done; float x,y; accept=0; done=0; int total=0,flag=0; int code0,code1,codeout; code0=CompCode(x0,y0,rect); printf("code0=%d\n",code0); code1=CompCode(x1,y1,rect); printf("code1=%d\n",code1); do{ if(!(code0|code1)) { accept=1; done=1; } else if(code0 & code1) { done=1;flag=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=x0+(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); } total++; if(total>2) { done=1;flag=1; } } }while(!done); if(accept) LineGL(x0,y0,x1,y1); else { x0=0;y=0;x1=0;y1=0; LineGL(x0,y0,x1,y1); } return accept; } void myDisplay() { glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0f,1.0f,1.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=200; //设置坐标系 原坐标应为(0,0)(2,0)(0,2)(2,2)改为(200,200)(400,200)(200,400)(400,400) rect.xmax=400; rect.ymin=200; rect.ymax=400; x0=100,y0=0,x1=500,y1=500; //为方便看,将原坐标(-1,-2)改为(100,0),(3,3)改为(500,500) } 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); //定义窗口大小 } int main(int argc,char *argv[]) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE); glutInitWindowPosition(100,100); glutInitWindowSize(640,480); glutCreateWindow("Cohen-Sutherland"); Init(); glutDisplayFunc(myDisplay); glutReshapeFunc(Reshape); glutMainLoop(); return 0; }