梁友栋-Barskey裁剪算法(附上c++源码)

最近在学习计算机图形学的基本算法,其中就看到了这一个剪裁算法,书上关于这个算法的讲解特别的少,感觉自己看不大懂这个算法,在网上找了一些资料,感觉都没有讲的特别清楚,后来我在一位博主的博客上找到了一篇讲得很好的博客,分享出来给大家:https://blog.csdn.net/soulmeetliang/article/details/79185603 这个博主是用matlab实现的,看懂之后,我决定用c++实现。

博主的实验环境:win10 + opengl + visual studio

直接贴代码:

 

 

//梁友栋-Barskey裁剪算法

 

#include "pch.h"

#include<gl/glut.h>

#include <iostream>

using namespace std;

 

//定义一条线

两个顶点(x1,y1)和(x2,y2)

struct Lines

{

int x1;

int y1;

int x2;

int y2;

};

 

//给出剪裁区域

int xleft = 200, xright = 400, ybuttom = 200, ytop = 400;

 

//虚拟出的直线,暂时有三条

Lines l1 = { 100,50,400,450 };

Lines l2 = { 200,100,400,300 };

Lines l3 = { 50,200,100,400 };

 

int cut_judge(float p, float q, float &u1, float &u2);

//画线

void LineGL(Lines &li) {

glBegin(GL_LINES);

glColor3f(0.0f, 1.0f, 0.0f);

glVertex2f(li.x1, li.y1);

glColor3f(0.0f, 1.0f, 0.0f);

glVertex2f(li.x2, li.y2);

glEnd();

}

//核心算法 更新线段的两端顶点

int LYD_Barskey(Lines &li) {

int accept = 0;

float u1 = 0.0, u2 = 1.0;

float dx = li.x2 - li.x1, dy = li.y2 - li.y1;

if (cut_judge(-dx, li.x1 - xleft, u1, u2)) {

if (cut_judge(dx, xright - li.x1, u1, u2)) {

if (cut_judge(-dy, li.y1 - ybuttom, u1, u2)) {

if (cut_judge(dy, ytop - li.y1, u1, u2)) {

if (u2 < 1.0) {

li.x2 = li.x1 + u2 * dx;

li.y2 = li.y1 + u2 * dy;

}

if (u1 > 0.0) {

li.x1 = li.x1 + u1 * dx;

li.y1 = li.y1 + u1 * dy;

}

accept = 1;

 

}

}

}

}

if (accept) {

 

LineGL(li);

}

else

{

li.x1 = 0;

li.y1 = 0;

li.x2 = 0;

li.y2 = 0;

LineGL(li);

}

return accept;

}

//更新u1和u2的值

int cut_judge(float p, float q, float &u1, float &u2) {

float u;

int res = 1;

if (p > 0.0) {

u = q / p;

if (u < u1) {

res = 0;

}

else if(u < u2)

{

u2 = u;

}

}

else if (p < 0.0) {

u = q / p;

if (u > u2) {

res = 0;

}

else if (u > u1) {

u1 = u;

}

}

else

{

if (q < 0.0) {

res = 0;

}

}

return res;

}

 

 

void Init() {

glClearColor(0.0, 0.0, 0.0, 0.0);

glShadeModel(GL_FLAT);

//按下c键会进行剪裁,按下r键会复原,按下x键会退出窗口

printf("Press key 'c' to Clip!\nPress key 'r' to Recover\nPress key 'x' to Exit\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 display() {//画图部分

 

glClear(GL_COLOR_BUFFER_BIT);

glColor3f(1.0f, 0.0f, 0.0f);

glPointSize(2);

//画矩形 使用的是红色

glBegin(GL_LINE_LOOP);

glVertex2f(200, 200);

glVertex2f(400, 200);

glVertex2f(400, 400);

glVertex2f(200, 400);

glEnd();

//画出最先开始的直线,没有经过任何修改

LineGL(l1);

LineGL(l2);

LineGL(l3);

glFlush();

}

 

//键盘监听事件

void keyboard(unsigned char key, int x, int y) {

switch (key) {

case 'c':

//按下c键以后,会进行裁剪工作

LYD_Barskey(l1);

LYD_Barskey(l2);

LYD_Barskey(l3);

glutPostRedisplay();//当前窗口重新绘制

break;

case 'r':

//按下r键以后,原来的直线恢复,出现原本的线

l1 = { 100,50,400,450 };

l2 = { 200,100,400,300 };

l3 = { 50,200,100,400 };

Init();

glutPostRedisplay();

break;

case 'x':

exit(0);

break;

default:

break;

}

}

 

 

int main(int argc,char *argv[])

{

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);

glutInitWindowPosition(400, 200);

glutInitWindowSize(500, 500);

glutCreateWindow("梁友栋-Barskey裁剪算法");

 

Init();

glutDisplayFunc(&display);

glutReshapeFunc(Reshape);

glutKeyboardFunc(&keyboard);//调用键盘监听事件

glutMainLoop();

 

return 0;

}

有问题请联系作者,看不懂代码的请先去前面的链接看原理!

  • 6
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值