最近计算机图形学,学习了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;
}
代码的运行结果:
如果直线在矩形裁剪窗口之内的部分为黑色,如果直线在矩形矩形裁剪窗口之外的部分为黄色,实现裁剪的效果。
直线在矩形窗口之外,为黄色。
直线在矩形窗口之内,则进行裁剪,裁剪之后的线段用黑色来表示: