opengl实现cs、liang-barsky直线裁剪算法

来源:互联网 发布:衬衣有哪些面料知乎 编辑:程序博客网 时间:2024/05/01 14:50
#include<glut.h>#include<iostream>#define L 00001#define R 00002#define B 00004#define T 00010#define M 00000#define LT 00011#define LB 00005#define RT 00012#define RB 00006//#define L 0x0001//#define R 0x0002//#define B 0x0004//#define T 0x0008//#define M 0x0000////#define LT 0x0009//#define LB 0x0005//#define RT 0x000a//#define RB 0x0006using namespace std;struct rectan {int xx0, yy0;int xx1, yy1;}rec;int temX = 0, tempY = 0;int c0 = 0, c1 = 0, c3 = 0;bool f = false;int CSLine(float xwl, float xwr, float ywb, float ywt, float x, float y) {   //得到编码区int temp = 0;if (x < xwl) {temp |= L;}else if (x > xwr) {temp |= R;}if (y < ywb) {temp |= B;}else if (y > ywt) {temp |= T;}return temp;}void CSLineP(int temp, float xwl, float xwr, float ywb, float ywt, float &x1, float &y1, float x2, float y2, float& x, float& y) {float k = (y2 - y1) / (x2 - x1);if ((temp & L) == 1) {y1 = y1 + k * (xwl - x1);x1 = xwl;}if ((temp & R) == 2) {y1 = y1 + k * (xwr - x1);x1 = xwr;}if ((temp & B) == 4 && y1 < ywb) {x1 = x1 + (ywb - y1) / k;y1 = ywb;}if ((temp & T) == 8 && y1 > ywt) {x1 = x1 + (ywt - y1) / k;y1 = ywt;}x = x1, y = y1;}void CSLine(float xwl, float xwr, float ywb, float ywt, float x1, float y1, float x2, float y2) {int code1 = CSLine(xwl, xwr, ywb, ywt, x1, y1);int code2 = CSLine(xwl, xwr, ywb, ywt, x2, y2);int flag = 0;if (code1 & code2) {flag = 0;}else if (code1 == 0 && code2 == 0) {flag = 1;}else {flag = 2;}if (flag == 1) {glBegin(GL_LINES);glVertex2f(x1, y1);glVertex2f(x2, y2);glEnd();}else if (flag == 2) {float newX1 = 0, newY1 = 0;float newX2 = 0, newY2 = 0;CSLineP(code1, xwl, xwr, ywb, ywt, x1, y1, x2, y2, newX1, newY1);//交换两点的坐标float tempx = x1, tempy = y1;x1 = x2;x2 = tempx;y1 = y2;y2 = tempy;CSLineP(code2, xwl, xwr, ywb, ywt, x1, y1, x2, y2, newX2, newY2);if (!(newX1 >= xwr && newX2 >= xwr) && !(newX1 <= xwl && newX2 <= xwl) && !(newY1 <= ywb && newY2 <= ywb) && !(newY1 >= ywt && newY2 >= ywt)) {glBegin(GL_LINES);glVertex2f(newX1, newY1);glVertex2f(newX2, newY2);glEnd();}}}void Init() {glClear(GL_COLOR_BUFFER_BIT);glLineWidth(5);if (c1 == 0) {glColor3f(0.f, 0.8f, 0.8f);glBegin(GL_LINES);glVertex2f(20, 120);glVertex2f(430, 440);glEnd();}glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);glColor3f(0.f, 0.8f, 0.5f);if (c1 > 0) {glRectf(rec.xx0, rec.yy0, rec.xx1, rec.yy1);c3 = 1;}if (c3 == 1) {glColor3f(1.0f, 0.0f, 0.0f);CSLine(rec.xx0, rec.xx1, rec.yy1, rec.yy0, 20, 120, 430, 440);}if (f) {glRectf(rec.xx0, rec.yy0, temX, tempY);}glutSwapBuffers();}void ChangeSize(GLsizei w, GLsizei h) {if (h == 0) {h = 1;}glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();glOrtho(0.0f, 600.f, 0.f, 600.f, 1.f, -1.f);glMatrixMode(GL_MODELVIEW);glLoadIdentity();}void mouseF(int button, int state, int x, int y) {if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {if (!f) {f = true;rec.xx0 = x;rec.yy0 = 600 - y;c0 = 1;}else {f = false;c1 = 1;rec.xx1 = x;rec.yy1 = 600 - y;glutPostRedisplay();}}if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {f = false;rec.xx0 = 0;rec.yy0 = 0;rec.xx1 = 0;rec.yy1 = 0;c1 = 0;c0 = 0;c3 = 0;glutPostRedisplay();}}void mouseMoveF(int x, int y) {if (f) {temX = x;tempY = 600 - y;glutPostRedisplay();}}void main(int argc, char **argv) {glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);glutInitWindowSize(600, 600);glutCreateWindow("CSLine");glutDisplayFunc(Init);glutReshapeFunc(ChangeSize);glutMouseFunc(mouseF);glutPassiveMotionFunc(mouseMoveF);glClearColor(0.f, 0.5f, 0.5f, 1.f);glutMainLoop();}
运行结果:
liang-barsky裁剪:
#include<glut.h>#include<iostream>using namespace std;int LBLineClipTest(float p, float q, float &umax, float &umin) {float r = 0.0;if (p < 0.0) {r = q / p;if (r > umin) {return 0;}else if (r > umax) {umax = r;}}else if (p > 0.0) {r = q / p;if (r < umax) {return 0;}else if (r < umin) {umin = r;}}else if (q < 0.0) {return 0;}return 1;}void LBLineClip(float xwl, float xwr, float ywb, float ywt, float x1, float y1, float x2, float y2) {float umax, umin, deltax, deltay, xx2, yy2, xx1, yy1;deltax = x2 - x1;deltay = y2 - y1;umax = 0.0;umin = 1.0;if (LBLineClipTest(-deltax, x1 - xwl, umax, umin)) {if (LBLineClipTest(deltax, xwr - x1, umax, umin)) {if (LBLineClipTest(-deltay, y1 - ywb, umax, umin)) {if (LBLineClipTest(deltay, ywt - y1, umax, umin)) {xx1 = int(x1 + umax*deltax + 0.5);yy1 = int(y1 + umax*deltay + 0.5);xx2 = int(x1 + umin*deltax + 0.5);yy2 = int(y1 + umin*deltay + 0.5);}glBegin(GL_LINES);glVertex2f(xx1, yy1);glVertex2f(xx2, yy2);glEnd();}}}}void RenderSence() {glClear(GL_COLOR_BUFFER_BIT);glPolygonMode(GL_FRONT_AND_BACK , GL_LINE);glLineWidth(5);glColor3f(1.0f, 0.0f, 0.0f);glRectf(20, 20, 120, 130);LBLineClip(20, 120, 20, 130, 30, 190, 80, 10);glFlush();}void ChangeSize(GLsizei w, GLsizei h) {if (h == 0) {h = 1;}glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();if (w <= h) {glOrtho(-100.0f, 250.0f, -100.0f, 250.0f * h / w, 1.0f, -1.0f);}else {glOrtho(-100.0f, 250.0f * w / h, -100.0f, 250.0f, 1.0f, -1.0f);}glMatrixMode(GL_MODELVIEW);glLoadIdentity();}void SetupRC() {glClearColor(0.0f, 0.5f, 0.5f, 1.0f);}void main(int argc, char **argv) {glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowSize(600, 600);glutCreateWindow("GLLine");glutDisplayFunc(RenderSence);glutReshapeFunc(ChangeSize);SetupRC();glutMainLoop();}


                                             
0 0
原创粉丝点击