要求:利用编码裁剪(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;
}