核心思想:

用参数方程表示一条直线

已知一条线段的起点(x1,y1)、终点(x2,y2),就可以通过一个参数u,表示这条线段所在直线上的任意一个点(x,y)

x=x1+u(x2-x1)

y=y1+u(y2-y1)

其中:

(x,y)是直线上任意一点

(x1,y1)是线段的起点

(x2,y2)是线段的终点

Δx是x2-x1

Δy是y2-y1

辅助概念

左下:入边

右上:出边

现在,

用u1表示可见部分的起点的参数u

用u2表示可见部分的终点的参数u

那么,

u1=max(0,ul,ub)

u2=min(1,ut,ur)

其中,

ul ub 分别是直线与窗口左边、下边交点的参数u

ut ur 分别是直线与窗口上边、右边交点的参数u

u=0表示起点

u=1表示终点

直线段的参数方程(一个参数u对应一个点)

u=0是起点,u=1是终点

x1,y1是起点

x2,y2是终点

现在我们要的是在窗口内的点,那么这些点的参数方程就要满足下面的不等式关系

我们关注的是参数u的值,要获取这些窗口内的点(x,y),就要知道它们的多个u值

为了方便,我们把不等式拆分成下面这个形式,均为小于号

每一行的u分别是ul、ur、ub、ut

再为了方便,用两个字母及其对应下标(8个变量)对不等式左右两边除了u的部分分别进行表记

数字与边的对应关系:

1l、2r、3b、4t

lb为入边,rt为出边

这就有了

现在我们就得到了u的表达式

uk是窗口边界及其延长线的交点的对应参数值,将这个参数值代入方程就可以获取该点的位置

算法举例:

算法的具体步骤:

(1)输入线段的起点、终点(x1,y1 )、(x2,y2)以及窗口边界的横纵坐标:wxl、wxr、wyb和wyt。w代表窗口,windows。l、r、b、t分别代表left、right、bottom、top。

(2)直线垂直的情况:

若△X=0,则p1=p2=0,此时进一步判断是否满足q1<0或q2<0 ,若满足,则该直线段不在窗口内,算法转(7)-结束。否则 ,满足q1≥0且q2≥0,则进一步计算umax和umin :

 算法转(5)

(3)直线水平的情况;

若△y=0,则p3=p4=0,此时进一步判断是否满足q3<0或q4<0 ,若满足,则该直线段不在窗口内,算法转(7)。否则,满 足q3 ≥0且q4 ≥0,则进一步计算umax和umin :

注:p的绝对值是横纵坐标的△x或△y,若p=0,就是平行于边界

如果p已经=0了,又同时有q<0,就是线段的起点在边界外,则线段在边界外

(4)一般情况:

若上述两条均不满足,则有pk≠0(k=1,2,3,4), 此时计算umax和umin:

(5)求得umax和umin后,进行判断:若umax>umin ,则直线段在窗口外,算法转(7)。若umax ≤umin,利用直线的参数方程

(6)利用直线的扫描转换算法绘制在窗口内的直线段

(7)算法结束

流程图:

附:作图地址

代码:

/**  clip.cpp*  This program clips the line with the given window.*/
#include <windows.h>
#include <glut.h>
#include <math.h>
#include <stdio.h>
#include <iostream>using namespace std;//矩形的四边界,使用函数表示法,比如x=L,表示矩形左边界所在直线
float L, R, B, T;void myinit(void)
{glShadeModel(GL_FLAT);glClearColor(0.0, 0.0, 0.0, 0.0);
}void myReshape(int w, int h)
{glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();if (w <= h)gluOrtho2D(0.0, 1.0, 0.0, 1.0*(GLfloat)h / (GLfloat)w);elsegluOrtho2D(0.0, 1.0*(GLfloat)w / (GLfloat)h, 0.0, 1.0);glMatrixMode(GL_MODELVIEW);
}//求裁剪后所得端点的u值,即在2组*3个u中,求出u的极大值、极小值
int getu(float p, float q, float* umax, float* umin)
{//假定当前点u的状态为可见int flag = 1;                           //flag为标志变量,0表示舍弃,1表示可见//参数ufloat u;//当前处理入边不等式,入边求大,小的点将直接被舍弃if (p < 0.0){//求参数uu = q / p;if (u < *umin)//这个点比最小的点还要小,舍弃flag = 0;else if (u > *umax)*umax = u;                        //求 入边umax}//当前处理出边不等式,出边求小,大的点将直接被舍弃else if (p > 0.0) {u = q / p;if (u > *umax)//这个点比最大的点还要小,舍弃flag = 0;else if (u < *umin)*umin = u;                        //求 出边umin}else if (q < 0 && p == 0)               //p=0,就是deltax或deltay=0,平行于边界。p<0并且q<0,平行或垂直线的点在边界外。 flag = 0;return flag;
}void myclip()
// line clipping algorithm 直线裁剪算法
{float dx, dy;float x1, x2, y1, y2;float umin, umax;umin = 0, umax = 1.0;cout << "输入线段的起点、终点(x1,y1)、(x2,y2):" << endl;cin >> x1 >> y1 >> x2 >> y2;//求出不等式中需要的dx、dydx = x2 - x1; dy = y2 - y1;//画一条线段glBegin(GL_LINES);glColor4f(0.0, 0.0, 0.0, 0.0);//设定线的端点glVertex2f(x1, y1);                     // 起点glVertex2f(x2, y2);                     // 终点//结束绘制glEnd();//分别求出不等式的四组u值,但凡有一组不等式判断直线不在边界内,返回子为0,直接结束if (getu(-dx, x1 - L, &umin, &umax))//求第一个不等式的u值,入边求大if (getu(dx, R - x1, &umin, &umax)) //求第二个不等式的u值,出边求小if (getu(-dy, y1 - B, &umin, &umax))//求第三个不等式的u值,入边求大if (getu(dy, T - y1, &umin, &umax))//求第四个不等式的u值,出边求小{if (umax < 1.0){x2 = x1 + umax * dx;  //求得裁剪后的终点 y2 = y1 + umax * dy;}if (umin > 0.0){x1 = x1 + umin * dx;  //求得裁剪后的起点y1 = y1 + umin * dy;}glBegin(GL_LINES);glColor4f(1.0, 0.0, 0.0, 1.0);glVertex2f(x1, y1);     // clipped line startpoint glVertex2f(x2, y2);     // clipped line endpoint glEnd();}
}void display(void)
{glClear(GL_COLOR_BUFFER_BIT);// ------------------------------------//  please define your own line segment and draw //  it here with different color and line width// ------------------------------------cout<<"请输入矩形的左、右、下、上边界:"<<endl;cin >> L>>R>>B>>T;glColor4f(0.7, 0.0, 0.7, 0.55);glBegin(GL_POLYGON);glVertex2f(L, B); // Bottom LeftglVertex2f(R, B); // Bottom LeftglVertex2f(R, T); // Bottom RightglVertex2f(L, T); // Bottom RightglEnd();//-------------------------------//do the clipping in myclip() funtion //-------------------------------myclip();// ------------------------------------//  please draw clipped line here with another //  color and line width// ------------------------------------   glFlush();
}/*  Main Loop*  Open window with initial window size, title bar,*  RGBA display mode, and handle input events.*/
int main(int argc, char** argv)
{glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);//define size and the relative positon of the applicaiton window on the displayglutInitWindowSize(500, 500);glutInitWindowPosition(100, 100);//init the defined window with "argv[1]" as topic showed on the top the windowglutCreateWindow(argv[0]);// opengl setupmyinit();//define callbacksglutDisplayFunc(display);glutReshapeFunc(myReshape);//enter the loop for displayglutMainLoop();return 1;
}

图形学 实验四 梁barsky算法相关推荐

  1. TIT 计算机图形学 实验三 使用重心坐标算法绘制颜色渐变的正六面体

    TIT 计算机图形学 实验三 使用重心坐标算法绘制颜色渐变的正六面体 前言 参考视频计算机图形学全套算法讲解和C++编码实现(共23讲配套源码),计算机图形学案例视频讲解以及主页相关算法.孔老师是我的 ...

  2. 计算机图形学 | 实验四:绘制一个球体

    计算机图形学 | 实验四:绘制一个球体 计算机图形学 | 实验四:绘制一个球体 封装Shader 为什么要封装Shader 如何使用 绘制球模型 球面顶点遍历 构造三角形图元 开启线框模式 开启面剔除 ...

  3. 计算机图形学——实验四 纹理映射实验

    实验四 纹理映射实验 实验项目性质:设计性实验 所属课程名称:计算机图形学A 实验计划学时:3学时 一.实验目的和要求 掌握纹理映射的基本原理,利用VC++ OpenGL实现纹理映射技术. 二.实验原 ...

  4. 【计算机图形学实验四——简单几何形体的平移、缩放、旋转等几何变换】

    一.实验内容.目的.要求 1.简单几何形体(三角形.多边形等)的平移.缩放.旋转等几何变换. 2.掌握相关算法的原理及实现 3.实现基础代码(非调用OpenGL等图形库): 缩放.旋转等能指定变换参考 ...

  5. 河北工业大学数据挖掘实验四 贝叶斯决策分类算法

    贝叶斯决策分类算法 一.实验目的 二.实验原理 1.先验概率和类条件概率 2.贝叶斯决策 三.实验内容和步骤 1.实验内容 2.实验步骤 3.程序框图 4.实验样本 5.实验代码 四.实验结果 五.实 ...

  6. 计算及图形学——实验四

    题一 // 提示:在合适的地方修改或添加代码 #include <GL/freeglut.h> #include<stdio.h> #include // 评测代码所用头文件- ...

  7. 计算机图形学实验四——投影变换

    这里写目录标题 一级目录 一级目录 [实验名称] 投影变换 [实验目的] 理解并掌握形体的投影变换的原理: [实验原理] 绘制一点透视图的变换矩阵: T= 1  0 0 0 0  1 0 0 0  0 ...

  8. 计算机图形学实验四 OpenGL的鼠标交互绘制

    一.实验目的 1.掌握OpenGL的鼠标按钮响应函数. 2.掌握OpenGL的鼠标移动响应函数. 3.进一步巩固OpenGL的基本图元绘制基础. 二.实验内容 1.鼠标画草图--实现鼠标点到哪,线就画 ...

  9. 计算机图形学基础(OpenGL版)实验四 直线裁剪

    计算机图形学基础 实验四 直线裁剪 1.实验目的: 了解二维图形裁剪的原理(点的裁剪.直线的裁剪.多边形的裁剪),利用VC+OpenGL实现直线的裁剪算法. 2.实验内容: (1) 理解直线裁剪的原理 ...

最新文章

  1. bash: vue: command not found
  2. js中substr,substring,indexOf,lastIndexOf的用法
  3. SIFT特征点匹配中KD-tree与Ransac算法的使用
  4. java将数据封装为树结构_JAVA代码实现多级树结构封装对象
  5. 深入解析C++编程中的静态成员函数
  6. 8年了,开始写点东西了
  7. 数据挖掘竞赛,算法刷题网址汇总
  8. 计算机不能代替人类英语,英语作文 谈谈计算机1我们已进入了计算机时代2计算机有许多优点3计算机不能代替人类...
  9. 从编程小白到全栈开发:服务的调用
  10. mysql8.0 i ha,centos7 mysql8.0 RPM软件包方式安装
  11. VirtualBox 6.1.4的共享剪贴板确实有问题,6.1.0正常
  12. 中国物联网发展年报出炉
  13. Git学习笔记--廖雪峰官网教程
  14. 力扣刷题 DAY_75 贪心
  15. mysqld: [ERROR] Found option without preceding group in config file【解决】
  16. 我的U盘终于中招啦:U盘快捷方式病毒
  17. mongo 查询,修改,批量修改
  18. 让Qt程序适配高分辨率屏幕,解决软件界面错乱异常
  19. laravel 简单聊聊singleton的实现过程
  20. SAP HR/HCM 定界的个人理解

热门文章

  1. Z1:第一台祖思机的架构与算法
  2. 比客户的变态需求更可怕的是,有一群“猪队友”!
  3. 扒一扒改变世界的十大算法
  4. 边玩游戏边学php,HTML5边玩边学(1)画布实现方法
  5. 计算机技术与消防,浅谈计算机技术在消防领域中的应用
  6. Softmax 函数和它的误解
  7. 让你飞速成长的18个故事
  8. 地震烈度速报崇州设7个播报台
  9. JavaWeb - 仿小米商城网(2) 用户注册
  10. 【爱的瓶子xp主题】