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

#include
#include
#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 0x0006
using 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();
}
运行结果:
opengl实现cs、liang-barsky直线裁剪算法_第1张图片
liang-barsky裁剪:

#include
#include
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();
}






你可能感兴趣的:(opengl,opengl,cs,liang-barsky,直线裁剪,鼠标裁剪)