计算机图形学5——Two-Dimensional Viewing and Clipping(二维线段裁剪算法)
采用Cohen-Sutherland算法裁剪线段
核心代码有:
bool line_clipping(CPoint2D p1, CPoint2D p2, CRect *cw,CPoint2D *q1, CPoint2D *q2)
// p1, p2: End points of input line segment
// cw: Clipping rectangle
// q1, q2: End points of output line segment
// Return value: true --- accept, false --- reject
{GLubyte code1,code2;GLint done=false,poltLine=false;GLfloat m;while(!done){code1=encode(p1,cw);//起点code2=encode(p2,cw);//终点if(accept(code1,code2)){done=true;poltLine=true;}else if(reject(code1,code2)){done=true;}else{if(inside(code1))//return GLint(!code);起点为0000,则交换起点和终点{swapPts(&p1,&p2);swapCodes(&code1,&code2);}if(p2.x!=p1.x)//斜率存在,便求斜率m=(p2.y-p1.y)/(p2.x-p1.x);//这里之前打错字了,导致显示不全//从右向左检查R1(起点且为外端点)if(code1&left){p1.y+=(cw->xmin-p1.x)*m;p1.x=cw->xmin;}else if(code1&right){p1.y+=(cw->xmax-p1.x)*m;p1.x=cw->xmax;}else if(code1&bottom){if(p2.x!=p1.x)p1.x+=(cw->ymin-p1.y)/m;p1.y=cw->ymin;}else if(code1&top){if(p2.x!=p1.x)p1.x+=(cw->ymax-p1.y)/m;p1.y=cw->ymax;}}}*q1=p1;*q2=p2;return poltLine;
}
完整代码如下:
// ====== Computer Graphics Experiment #6 ======
// | Two-Dimensional Viewing and Clipping |
// =============================================
//
// Requirement:
// (1) Implement Cohen-Sutherland line clipping algorithm.
// (2) Change position and size of window and viewport
// and observe the effects.#include
#include
#include // 2D point class
class CPoint2D
{
public:float x, y;
};// Rectangle class
class CRect
{
public:float xmin, ymin, xmax, ymax;float width(void) { return xmax-xmin; }float height(void) { return ymax-ymin; }// Make (xmin, ymin) the lower left cornervoid normalize(void);// Draw the rectanglevoid draw(GLenum mode);};void CRect::normalize(void)
{float ftemp;if (xmin > xmax){ftemp=xmin; xmin=xmax; xmax=ftemp;}if (ymin > ymax){ftemp=ymin; ymin=ymax; ymax=ftemp;}
}void CRect::draw(GLenum mode)
{glBegin(mode);glVertex2f(xmin, ymin);glVertex2f(xmax, ymin);glVertex2f(xmax, ymax);glVertex2f(xmin, ymax);glEnd();
}#define PI 3.14159265359int running_state=0;
// 0 --- Normal state.
// 1 --- Rubber-band state.// Size of the scene
float scene_size=1000.0;CRect clip_rect; // Clipping rectangle
CRect window; // Window
CRect viewport; // Viewport// Program window size
int pw_width, pw_height;// Set window
void set_window(CRect *cw)
{glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D (cw->xmin, cw->xmax, cw->ymin, cw->ymax);
}// Set viewport
void set_viewport(CRect *vp)
{glViewport(vp->xmin, vp->ymin,vp->width(), vp->height());
}const GLint left=0x1;
const GLint right=0x2;
const GLint bottom=0x4;
const GLint top=0x8;GLint inside(GLint code)
{return GLint(!code);
}
GLint reject(GLint code1,GLint code2)
{return GLint(code1&code2);
}
GLint accept(GLint code1,GLint code2)
{return GLint(!(code1|code2));
}
GLubyte encode(CPoint2D pt,CRect *cw1)/
{GLubyte code=0x00;if(pt.x<cw1->xmin)code=code|left;if(pt.x>cw1->xmax)code=code|right;if(pt.y<cw1->ymin)code=code|bottom;if(pt.y>cw1->ymax)code=code|top;return(code);
}void swapPts(CPoint2D *p1,CPoint2D *p2)
{CPoint2D temp;temp=*p1;*p1=*p2;*p2=temp;
}void swapCodes(GLubyte *p1,GLubyte*p2)
{GLubyte temp;temp=*p1;*p1=*p2;*p2=temp;
}
// Cohen-Sutherland line clipping algorithm.
bool line_clipping(CPoint2D p1, CPoint2D p2, CRect *cw,CPoint2D *q1, CPoint2D *q2)
// p1, p2: End points of input line segment
// cw: Clipping rectangle
// q1, q2: End points of output line segment
// Return value: true --- accept, false --- reject
{GLubyte code1,code2;GLint done=false,poltLine=false;GLfloat m;while(!done){code1=encode(p1,cw);//起点code2=encode(p2,cw);//终点if(accept(code1,code2)){done=true;poltLine=true;}else if(reject(code1,code2)){done=true;}else{if(inside(code1))//return GLint(!code);起点为0000,则交换起点和终点{swapPts(&p1,&p2);swapCodes(&code1,&code2);}if(p2.x!=p1.x)//斜率存在,便求斜率m=(p2.y-p1.y)/(p2.x-p1.x);//这里之前打错字了,导致显示不全//从右向左检查R1(起点且为外端点)if(code1&left){p1.y+=(cw->xmin-p1.x)*m;p1.x=cw->xmin;}else if(code1&right){p1.y+=(cw->xmax-p1.x)*m;p1.x=cw->xmax;}else if(code1&bottom){if(p2.x!=p1.x)p1.x+=(cw->ymin-p1.y)/m;p1.y=cw->ymin;}else if(code1&top){if(p2.x!=p1.x)p1.x+=(cw->ymax-p1.y)/m;p1.y=cw->ymax;}}}*q1=p1;*q2=p2;return poltLine;
}//Translate the clip rectangle
void Translaterect(int dx,int dy)
{clip_rect.xmin+=dx;clip_rect.xmax+=dx;clip_rect.ymin+=dy;clip_rect.ymax+=dy;
}// Initialization function
void init(void)
{glClearColor (0.0, 0.0, 0.0, 0.0);glEnable(GL_LINE_STIPPLE);
}// Display callback function
void display(void)
{int i;CPoint2D p1, p2, q1, q2;double a, r;glClear (GL_COLOR_BUFFER_BIT);// Draw blue rectangle to fill the backgroundglColor3f(0.0, 0.0, 0.5);window.draw(GL_POLYGON);// Draw unclipped lines in green colorp1.x=0.0; p1.y=0.0;r=0.5*scene_size;glLineStipple(1, 0x0f0f);glColor3f(0.0, 1.0, 0.0);glBegin(GL_LINES);for (i=0; i<360; i+=15){a=(double)i/180.0*PI;p2.x=r*cos(a);p2.y=r*sin(a);if (i==0 || i==180) p2.y=0;if (i==90 || i==270) p2.x=0;p2.x+=p1.x;p2.y+=p1.y;glVertex2f(p1.x, p1.y);glVertex2f(p2.x, p2.y);}glEnd();glLineStipple(1, 0xffff);// Draw clipped lines in white colorif (running_state == 0) {glColor3f(1.0, 1.0, 1.0);glLineWidth(2.0);glBegin(GL_LINES);for (i=0; i<360; i+=15){a=(double)i/180.0*PI;p2.x=r*cos(a);p2.y=r*sin(a);if (i==0 || i==180) p2.y=0;if (i==90 || i==270) p2.x=0;p2.x+=p1.x;p2.y+=p1.y;if(line_clipping(p1, p2, &clip_rect, &q1, &q2)){glVertex2f(q1.x, q1.y);glVertex2f(q2.x, q2.y);}}glEnd();glLineWidth(1.0);}// Draw clipping rectangleglLineStipple(1, 0x0f0f);glColor3f(1.0, 1.0, 0.0);clip_rect.draw(GL_LINE_LOOP);glLineStipple(1, 0xffff);glutSwapBuffers();
}// Reshape callback functionvoid reshape(int w, int h)
{// Store program window sizepw_width=w;pw_height=h;// set viewportviewport.xmin=0;viewport.xmax=w;viewport.ymin=0;viewport.ymax=h;set_viewport(&viewport);// set clipping windowwindow.xmin=-0.6*scene_size;window.xmax=0.6*scene_size;window.ymin=-0.6*scene_size;window.ymax=0.6*scene_size;set_window(&window);// set clipping rectangleclip_rect.xmin=0.5*window.xmin;clip_rect.xmax=0.5*window.xmax;clip_rect.ymin=0.5*window.ymin;clip_rect.ymax=0.5*window.ymax;
}// Keyboard callback function
void keyboard(unsigned char key, int x, int y)
{switch (key) {case 27:exit(0);}
}// Special keyboard callback function
void special_key(int key, int x, int y)
{switch (key) {case GLUT_KEY_LEFT:Translaterect(-5,0);glutPostRedisplay();break;case GLUT_KEY_RIGHT:Translaterect(5.0,0.0);glutPostRedisplay();break;case GLUT_KEY_DOWN:Translaterect(0.0,-5.0);glutPostRedisplay();break;case GLUT_KEY_UP:Translaterect(0.0,5.0);glutPostRedisplay();break;}
}// Main program entrance
int main(int argc, char* argv[])
{glutInit(&argc, argv);glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE);glutInitWindowSize(500, 500);glutCreateWindow("Test 2D Clippig and Viewing");init();glutReshapeFunc(reshape);glutKeyboardFunc(keyboard);glutSpecialFunc(special_key);glutDisplayFunc(display);glutMainLoop();return 0;
} 
考虑到我修改出这篇文章的代码花了不少时间,
应该算是原创的一种了
(っ °Д °;)っ
转载于:https://www.cnblogs.com/vivid-victory/p/10090459.html
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
