学习过三种画直线的方法(DDA、中点Bresenham算法、改进的中点Bresenham算法)后,想着实际操作一下如何能够实现,OpenGL无疑是很好的选择,在老师的推荐下,我尝试着用OpenGL来实现中点Bresenham算法画直线,最后也基本实现了这个功能。

如果有不正确或者能更好改进的地方欢迎各位大神留言或私信指教。

基本原理:每次在最大位移方向上走一步,而另一个方向是走步还是不走步取决于误差项的判别。(|k|<1时x是最大位移方向,|k|>1时y是最大位移方向)

推导过程:

举0<k<1的例子:首先要写出直线的一般方程,根据基本原理,在最大位移方向上走一步时,另一个方向是否走步取决于误差项(di)的判断。

M点是网格的中点,误差项 从图中可以看出,当M点在直线下方时,也就是di<0时,直线靠近上面的B点;当M点在直线上方时,也就是di>0时,直线靠近下面的A点。从而我们可以得到:这样就画好了一个点。

进行误差项的递推我们可以得到:

对于di的初始值

做完这些我们就可以得到该算法的步骤是:

1.输入直线的两端点P0(x0,y0)和Pn(xn,yn);

2.计算初始值△x、△y、d0=0.5-k、x=x0、y=y0;

3.绘制点(x,y)。判断d的符号;

若d<0,则(x,y)更新为(x+1,y+1),d更新为 d+1-k;

否则(x,y)更新为(x+1,y),d更新为 d-k。

4.当直线没有画完时,重复步骤3。否则结束。

由于式子中包含小数影响速度,所以我们对此进行改进:用2d∆x代替d,这样我们就能得到完整的中点Bresenham算法画直线的步骤啦!

改进之后若d<0,则(x,y)更新为(x+1,y+1),d更新为d+2∆x-2∆y;

否则(x,y)更新为(x+1,y),d更新为d-2∆y。

以上只是0<k<1时的情况,还有三种情况请读者自己推导加深印象。

本人的开发环境是VS2022+OpenGL+C#

代码演示:

void MidBresenhamLine(float x0, float y0, float x1, float y1)
{float dx, dy, d, up, down, x, y, k;if (x0 > x1){x = x1;x1 = x0;x0 = x;y = y1;y1 = y0;y0 = y;}x = x0;y = y0;dx = x1 - x0;dy = y1 - y0;k = dy / dx;//斜率  putpixel(x, y);if (k <= 1 && k > 0)//斜率小于等于1且大于等于0的情况{//用2*dx*d代替dd = dx - 2 * dy;up = 2 * dx - 2 * dy;down = -2 * dy;while (x <= x1){x++;//x为最大位移方向if (d < 0){y++;d += up;}else{d += down;}putpixel(x, y);}}else if (k > 1)//斜率大于1的情况{d = 2 * dx - dy;up = 2 * dx;down = 2 * dx - 2 * dy;while (x <= x1){y++;//y是最大位移方向if (d < 0){d += up;}else{x++;d += down;}putpixel(x, y);}}else if (k < -1)//斜率小于等于-1的情况{d = -2 * dx - dy;up = -2 * dx - 2 * dy;down = -2 * dx;while (x <= x1){y--;//y是最大位移方向if (d < 0){x++;d += up;}else{d += down;}putpixel(x, y);}}else if (k <= 0 && k >= -1)//斜率小于0且斜率大于-1的情况{d = -dx - 2 * dy;up = -2 * dy;down = -2 * dx - 2 * dy;while (x <= x1){x++;//x为最大位移方向if (d < 0){d += up;}else{y--;d += down;}putpixel(x, y);}}
}

中点Bresenham算法的优点是:

  1. 不用计算直线的斜率,不做除法;
  2. 不考虑浮点数,只考虑整数;
  3. 只做整数加减法和乘2运算,乘2运算可以用硬件移位实现;
  4. 算法速度快并适用于硬件实现。

缺点在我看来就是精度不如DDA

完整代码示例:

#include<stdio.h>
#include<math.h>
#include<GL/glut.h>void init()
{glClearColor(1.0, 1.0, 1.0, 1.0);//表示清除颜色设为白色glMatrixMode(GL_PROJECTION);//操作投影矩阵gluOrtho2D(0.0, 30.0, 0.0, 30.0);//正射投影(二维图像投影到二维平面上),左下角x为0,左上角x为30,右下角y为0,右上角y为30
}
void putpixel(float x, float y)//画点
{glColor3f(0.0, 0.0, 1.0);//画的点的颜色:蓝色glPointSize(5.0f);//设置点的大小glBegin(GL_POINTS);//表示单个顶点glVertex2i(60+x, 80+y);//定义顶点,2代表二维有代表参数列表参数的个数,f代表浮点型glEnd();//与glBegin搭配使用glFlush();//强制刷新
}
void MidBresenhamLine(float x0, float y0, float x1, float y1)
{float dx, dy, d, up, down, x, y, k;if (x0 > x1){x = x1;x1 = x0;x0 = x;y = y1;y1 = y0;y0 = y;}x = x0;y = y0;dx = x1 - x0;dy = y1 - y0;k = dy / dx;//斜率  putpixel(x, y);if (k <= 1 && k > 0)//斜率小于等于1且大于等于0的情况{//用2*dx*d代替dd = dx - 2 * dy;up = 2 * dx - 2 * dy;down = -2 * dy;while (x <= x1){x++;//x为最大位移方向if (d < 0){y++;d += up;}else{d += down;}putpixel(x, y);}}else if (k > 1)//斜率大于1的情况{d = 2 * dx - dy;up = 2 * dx;down = 2 * dx - 2 * dy;while (x <= x1){y++;//y是最大位移方向if (d < 0){d += up;}else{x++;d += down;}putpixel(x, y);}}else if (k < -1)//斜率小于等于-1的情况{d = -2 * dx - dy;up = -2 * dx - 2 * dy;down = -2 * dx;while (x <= x1){y--;//y是最大位移方向if (d < 0){x++;d += up;}else{d += down;}putpixel(x, y);}}else if (k <= 0 && k >= -1)//斜率小于0且斜率大于-1的情况{d = -dx - 2 * dy;up = -2 * dy;down = -2 * dx - 2 * dy;while (x <= x1){x++;//x为最大位移方向if (d < 0){d += up;}else{y--;d += down;}putpixel(x, y);}}
}void ChangeSize(GLsizei w, GLsizei h) {if (h == 0)h = 1;glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();if (w <= h)glOrtho(0.0f, 250.0f, 0.0f, 250.0f * h / w, 1.0, -1.0);elseglOrtho(0.0f, 250.0f * w / h, 0.0f, 250.0f, 1.0, -1.0);
}
void display()
{glClear(GL_COLOR_BUFFER_BIT);MidBresenhamLine(0, 0, 120, 80);//在此处修改点的位置
}
int main(int argc, char** argv)
{glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowSize(400, 400);//画图窗口大小glutInitWindowPosition(0, 0);//在显示屏上的位置:(0,0)代表左上角glutCreateWindow("中点bresenham算法画直线");//窗口名称glutDisplayFunc(display);//调用display函数绘制窗口init();glutReshapeFunc(ChangeSize);glutMainLoop();return 0;
}

结果(我输入的起点坐标是(0,0),终点坐标是(120,80))如图:

以上就是中点Bresenham算法的全部内容了,如有错误和更好的地方请多多指教,谢谢大家!

【计算机图形学】基于OpenGL的中点Bresenham算法画直线相关推荐

  1. 计算机图形学04:中点Bresenham算法画椭圆

    作者:非妃是公主 专栏:<计算机图形学> 博客地址:https://blog.csdn.net/myf_666 个性签:顺境不惰,逆境不馁,以心制境,万事可成.--曾国藩 文章目录 专栏推 ...

  2. 计算机图形学E2——OpenGL Bresenham算法画直线

    其他计算机图形学实验见 链接 要求 使用Bresemham算法画直线,并且通过鼠标可以实现交互操作 参考代码: 代码1 代码2 代码3(代码好理解) 代码4(讲解很全面) #include<io ...

  3. 布兰森汉姆画圆matlab,bresenham算法画直线

    实验一名称:基本图形的生成算法 要求:(1)掌握 DDA 生成线段算法 (2)掌握 Bresenham 生成线段算法 (3)掌握生成圆弧算法 1. 代码 (1) Bresenham 画线算法 v 实验 ...

  4. c语言图形学扫描线填充算法,《计算机图形学》OpenGL实现扫描线填充算法

    顾名思义啊,就是在OpenGL中用扫描填充算法画一个稍微复杂的图形: #include #include #include #include #define COLOR_NEW 1.0,0.0,0.0 ...

  5. 使用openGL,用Bresenham算法画椭圆

    运行结果 源代码 //用Bresenham算法画椭圆 #include<iostream> #include<stdlib.h> #include <GL/glut.h& ...

  6. Bresenham算法画直线

    本博客仅限于斜率在0~1之间的直线 原算法 设直线起始点坐标为(xs,ys),均为整数,即 x1 = xs, y1 = ys e(x2) = y2 - y1 - 0.5 = m - 0.5 终点坐标为 ...

  7. Bresenham 算法画直线

    参考:Bresenham 画线算法推导过程_在到处之间找我-CSDN博客_bresenham画线算法今天复习这个算法的时候,有一点没有立马反应过来,故特此记此篇博客作为备忘.文章目录描点原理用 $p_ ...

  8. 计算机图形学及OpenGL简介摘记

    计算机图形学(Computer Graphics)是研究怎样用计算机表示.生成.处理和显示图形的一门学科.图形的具体应用范围很广,但是按基本的处理技术划分只有两类.一类是线条,如工程图.地图.曲线图表 ...

  9. 计算机图形学-抛物线的中点Bresenham算法

    抛物线 f ( x ) = a x 2 f(x)=ax^2 f(x)=ax2的中点Bresenham算法 语言:matlab 画图:plot 1 抛物线的特征 通常定义抛物线为到一条直线(准线)和直线 ...

最新文章

  1. 毕业设计:基于Web实现多用户宿舍管理系统
  2. Slog64_项目上线之ArthurSlog个人网站上线3
  3. 基于AES加解密的图像加解密算法
  4. jvm性能调优实战 - 25模拟在Young GC过后因为放入下Survivor区域直接进入老年代
  5. 利用JS脚本快速删除百度网盘同一目录下的不需要文件(可以参考这个方法删除重复文件)
  6. 微信小程序动态点赞php,在微信小程序中如何实现点赞功能
  7. 在函数中的局部程序(像是比局部变量还局部的部分)
  8. 52 -算法 -数据结构类 Leetcode26 删除有序数组中的重复项
  9. Hadoop HIVE 创建表
  10. Ubuntu中DenyHosts清除黑名单IP地址
  11. idea console窗口不见了_Python 闲谈 14——安利下IDEA开发神器中好用到爆的插件
  12. c语言程序输出三角,C语言小程序之输出“上三角”
  13. 随机效应估算与固定效应估算_短面板数据学习手册(固定效应与随机效应等汇总)...
  14. Mac下如何显示隐藏文件
  15. 2018年中国房地产行业现状及行业发展趋势分析【转】
  16. 2018.12.31 NOIP训练 czy的后宫6(线性dp)
  17. 六张图片形成立方体并旋转
  18. 大S产女获张兰连续两天探望 大赞儿媳妇是骄傲
  19. 打印机打开扫描提示使用该设备需要WIA驱动程序。请从安装CD或从制造商的网站安装此程序,然后重试--------
  20. Flask项目能打包为单个exe文件运行?掌握原理后居然如此简单!

热门文章

  1. EC200U open方案环境搭建
  2. python编程:从入门到实践 阅读笔记
  3. python tkinter画布设置按钮对图片放大缩小_Tkinter可调整大小的对象Python画布
  4. 手机端网页设计尺寸,手机端网页设计图片尺寸
  5. 王的机器第一本书「快乐机器学习」飨你
  6. 腾讯TDSQL全时态数据库系统论文入选VLDB
  7. R语言学习 文本处理
  8. 平均获客成本_互联网金融获客成本
  9. 手机加上芯片可看免费电视 明年国内将上市(图)
  10. CleanMyMac4.13最新免费mac电脑系统优化软件