Liang-Barsky直线段裁剪

在这里插入图片描述
在这里插入图片描述

随便记一下书上的代码
好多奇怪的BUG哦。

#include<gl/glut.h>
#include<stdio.h>
#include<stdlib.h>
bool bInput, accept, bDraw;
struct ClipWindow {
	float xmin, ymin, xmax, ymax;
}rect;
struct Point {
	int x, y;
}pt[2];
void LineGL(Point pt0, Point pt1) {
	glBegin(GL_LINES);
	glColor3f(0.0f, 0.0f, 0.0f);
	glVertex2f(pt0.x, pt0.y);
	glColor3f(0.0f, 0.0f, 0.0f);
	glVertex2f(pt1.x, pt1.y);
	glEnd();
}
void PointGL(Point pt) {
	glPointSize(2);
	glBegin(GL_POINTS);
	glColor3f(0.0f, 0.0f, 0.0f);
	glVertex2f(pt.x, pt.y);
	glEnd();
}
int clipTest(float p, float q, float *u1, float *u2) {
	float r;;
	int retVal = 1;
	if (p < 0) {
		r = q / p;
		if (r > *u2)retVal = 0;//(起点到裁剪边界投影距离/起点到终点投影距离) 大于1,终点未能抵达边界,无交
		else if (r > *u1)*u1 = r;
	} else if (p > 0) {
		r = q / p;
		if (r < *u1)retVal = 0;//(起点到裁剪边界投影距离/起点到终点投影距离) 小于0,起点已经越过边界,无交
		else if (r < *u2)*u2 = r;
	} else if (q < 0)retVal = 0;
	return retVal;
}
int L_B_LineClip(Point pt1, Point pt2, ClipWindow rect) {
	float x1, y1, x2, y2;
	x1 = pt1.x;
	x2 = pt1.y;
	y1 = pt2.x;
	y2 = pt2.y;
	float u1 = 0, u2 = 1, dx = x2 - x1, dy;
	if (clipTest(-dx, x1 - rect.xmin, &u1, &u2))
		if (clipTest(dx, rect.xmax - x1, &u1, &u2)) {//&&
			dy = y2 - y1;
			if (clipTest(-dy, y1 - rect.ymin, &u1, &u2))
				if (clipTest(dy, rect.ymax - y1, &u1, &u2)) {
					if (u2 < 1) {
						x2 = x1 + u2 * dx;
						y2 = y1 + u2 * dy;
						pt[1].x = x2;
						pt[1].y = y2;
					}
					if (u1 > 0) {
						x1 += u1 * dx;
						y1 += u1 * dy;
						pt[0].x = x1;
						pt[0].y = y1;
					}
					return 1;
				}
		}
	return 0;
}
void myDisplay() {
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(1.0f, 1.0f, 1.0f);
	glRectf(rect.xmin, rect.ymin, rect.xmax, rect.ymax);
	if (accept) {
		if (bDraw) 
			LineGL(pt[0], pt[1]);
		else PointGL(pt[0]);
	}
	glFlush();
}
void Init() {
	glClearColor(0.5, 0.5, 0.5, 0.0);
	glShadeModel(GL_SMOOTH);
	rect.xmin = 250;
	rect.xmax = 450;
	rect.ymin = 200;
	rect.ymax = 400;
	accept = true;
	bInput = false;
	printf("Press Left Mouse Button to Draw two Point to create a line!\n");
	printf("Press key 'c' to Clip!\n");
}
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);
}
void keyboard(unsigned char key, int x, int y) {
	switch (key) {
		case 'c':
			if (L_B_LineClip(pt[0], pt[1], rect))glutPostRedisplay();
			else {
				bDraw = false;
				glutPostRedisplay();
			}
			break;
		case 'r':
			Init();
			bDraw = false;
			glutPostRedisplay();
			break;
	default:
		break;
	}
}
void mouse(int button, int state, int x, int y) {
	switch (button) {
	case GLUT_LEFT_BUTTON:
		if (state == GLUT_DOWN) {
			if (bInput == false) {
				pt[0].x = x;
				pt[0].y = 480-y;//转成向上的y
				bInput = true;
				bDraw = false;
				accept = true;
				glutPostRedisplay();
			}
			else {
				pt[1].x = x;
				pt[1].y = 480 - y;
				bDraw = true;
				bInput = false;
				glutPostRedisplay();
			}
		}
		break;
	default:
		break;
	}
}
int main(int argc, char **argv) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
	glutInitWindowPosition(500, 200);
	glutInitWindowSize(640, 480);
	glutCreateWindow("LB直线段裁剪算法");
	Init();
	glutDisplayFunc(myDisplay);
	glutReshapeFunc(Reshape);
	glutKeyboardFunc(keyboard);
	glutMouseFunc(mouse);
	glutMainLoop();
	return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值