Liang-Barskey算法以及代码实现

最近计算机图形学,学习了Liang-Barskey算法,然后实现了Liang-Barskey算法,对于Liang-Barskey算法的原理和含义,可以下一篇博客,讲述了 Liang-Barskey算法的原理。

https://blog.csdn.net/ZY_cat/article/details/78293266

具体实现,如图类似:

 

Liang-Barskey 的代码如下:

  代码的思路:画一个矩形,来作为一个裁剪窗口,然后画一条黄色的直线。如果直线没有经过矩形区域,则为黄色,如果穿过矩形区域,则使用Liang-Barskey算法来进行裁剪,裁剪之后,再进行画一条黑色的直线来覆盖。

 

#include <iostream>
#include<GL/glut.h>
#include<Windows.h>
using namespace std;
#define ww 640   //屏幕的宽度
#define wh 480   //屏幕的高度
int xs, ys, xb, yb;
int rl = 200, rb = 200;
int rr = 400, rt = 400;
bool first;
//画线的方法
void lineNew(int x0, int y0, int xEnd, int yEnd)
{
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(1.0f, 1.0f, 0.0f);  //画黄色
	glLineWidth(3);
	glBegin(GL_LINES);
	glVertex2f(x0, y0);
	glVertex2f(xEnd, yEnd);
	glEnd();

	glFlush();
}


void myDisplay() {

	glClear(GL_COLOR_BUFFER_BIT); //清空颜色缓冲池 
	glColor3f(1.0f, 0.0f, 0.0f); //设置绘图颜色 
	glRectf(rl,rb,rr,rt); //绘制矩形
	glFlush(); //执行OpenGL指令列表中的指令 
}
bool ClipT(float p, float q, float *u1, float *u2) {
	float r;
	if (p < 0) {
		r = q / p;
		if (r > *u2) {
			return FALSE;
		}
		if (r > *u1) {
			*u1 = r;
		}
	}
	else if (p > 0) {
		r = q / p;
		if (r < *u1) {
			return FALSE;
		}
		if (r < *u2) {
			*u2 = r;
		}
	}
	else {
				return q >= 0;
	}
	return TRUE;
}



void LB_LineClip(float x1, float y1, float x2, float y2, float XL, float XR, float YB, float YT) {
	float dx, dy, u1, u2;
	u1 = 0;
	u2 = 1;
	dx = x2 - x1;
	dy = y2 - y1;
	if (ClipT(-dx,x1-XL,&u1,&u2)) {
		if (ClipT(dx, XR - x1, &u1, &u2)) {
			if (ClipT(-dy, y1 - YB, &u1, &u2)) {
				if (ClipT(dy, YT - y1, &u1, &u2)) {
					glLineWidth(3);
					glColor3f(0.0, 0.0, 0.0);//黑色
					glBegin(GL_LINES);

					glVertex2f(x1 + u1 * dx, y1 + u1 * dy);
					glVertex2f(x1 + u2 * dx, y1 + u2 * dy);
					glEnd();
					glFlush();
				}
			}
		}
	}
}
void Init() {
	glClearColor(1.0, 1.0, 1.0, 0.0); //即窗口的背景色
	glClear(GL_COLOR_BUFFER_BIT);      //清除颜色缓冲区,即窗口的背景色
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluOrtho2D(0.0,ww, 0.0, wh);

}
void myMouse0(int button, int state, int x, int y)
{
	glBegin(GL_POINTS);
	if (button == GLUT_LEFT_BUTTON)
	{
		if (state == GLUT_DOWN) {
			xs = x;
			ys = wh - y;
			glVertex2i(xs, ys);
			first = 0;
		}
		else {
			xb = x;
			yb = wh - y;
			first = 1;
		}
		if (first) {
			lineNew(xs, ys, xb, yb);
			LB_LineClip(xs, ys, xb, yb, rl, rr, rb, rt);
		}

	}
	glEnd();
	glFlush(); //glFlush()清空缓冲区,将指令送往缓硬件立即执行
}

int main()
{
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowSize(ww, wh);
	glutInitWindowPosition(100, 150);
	glutCreateWindow("Liang-Barskey");
	Init();
	glutDisplayFunc(myDisplay);
	glutMouseFunc(myMouse0);

	glutMainLoop();  //持续显示,当窗口改变会重新绘制图形
	return 0;
}

 

代码的运行结果:

如果直线在矩形裁剪窗口之内的部分为黑色,如果直线在矩形矩形裁剪窗口之外的部分为黄色,实现裁剪的效果。

直线在矩形窗口之外,为黄色。

 

直线在矩形窗口之内,则进行裁剪,裁剪之后的线段用黑色来表示:

 

 

 

 

  • 9
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值