转自:https://www.cnblogs.com/soroman/archive/2006/07/27/509602.html

以前看到Bresenham画线算法,直接拿来用,没有去推导它,近日,参考一些资料,特整理其算法推导过程如下。各位大虾如果知道其细节,赶紧闪过,不用浪费时间了。

基本上Bresenham画线算法的思路如下:

// 假设该线段位于第一象限内且斜率大于0小于1,设起点为(x1,y1),终点为(x2,y2).
// 根据对称性,可推导至全象限内的线段.
1.画起点(x1,y1).
2.准备画下个点。x坐标增1,判断如果达到终点,则完成。否则,由图中可知,下个要画的点要么为当前点的右邻接点,要么是当前点的右上邻接点.
2.1.如果线段ax+by+c=0与x=x1+1的交点的y坐标大于M点的y坐标的话,下个点为U(x1+1,y1+1)
2.2.否则,下个点为B(x1+1,y1)
3.画点(U或者B).
4.跳回第2步.
5.结束.

这里需要细化的是怎么判断下个要画的点为当前点的右邻接点还是当前点的右上邻接点.

设线段方程:ax+by+c=0(x1<x<x2,y1<y<y2)
令dx=x2-x1,dy=y2-y1
则:斜率-a/b = dy/dx.

从第一个点开始,我们有F(x,1,y1) = ax1+by1+c=0
下面求线段ax+by+c=0与x=x1+1的交点:
由a*(x1+1)+b*y+c = 0, 求出交点坐标y=(-c-a(x1+1))/b
所以交点与M的y坐标差值Sub1 = (-c-a(x1+1))/b - (y1+0.5) = -a/b-0.5,即Sub1的处始值为-a/b-0.5。

则可得条件当 Sub1 = -a/b-0.5>0时候,即下个点为U.
反之,下个点为B.
代入a/b,则Sub1 = dy/dx-0.5.

因为是个循环中都要判断Sub,所以得求出循环下的Sub表达式,我们可以求出Sub的差值的表达式.下面求x=x1+2时的Sub,即Sub2
1.如果下下个点是下个点的右上邻接点,则
Sub2 = (-c-a(x1+2))/b - (y1+1.5) = -2a/b - 1.5
故Sub差值Dsub = Sub2 - Sub1 = -2a/b - 1.5 - (-a/b-0.5) = -a/b - 1.代入a/b得Dsub = dy/dx -1;
2.如果下下个点是下个点的右邻接点,
Sub2 = (-c-a(x1+2))/b - (y1+0.5) = -2a/b - 0.5
故Sub差值Dsub = Sub2 - Sub1 = -2a/b - 0.5 - (-a/b-0.5) = -a/b. 代入a/b得Dsub = dy/dx;

于是,我们有了Sub的处始值Sub1 = -a/b-0.5 = dy/dx-0.5,又有了Sub的差值的表达式Dsub = dy/dx -1 (当Sub1 > 0)或 dy/dx(当Sub1 < 0).细化工作完成。

于是pcode可以细化如下:

// Pcode for Bresenham Line
// By SoRoMan
x=x1;
y=y1;
dx = x2-x1;
dy = y2-y1;
Sub = dy/dx-0.5; // 赋初值,下个要画的点与中点的差值

DrawPixel(x, y); // 画起点
while(x<x2)
{
x++;
if(Sub > 0) // 下个要画的点为当前点的右上邻接点
{
Sub += dy/dx - 1; //下下个要画的点与中点的差值
y++; // 右上邻接点y需增1
}
else// 下个要画的点为当前点的右邻接点
{
Sub += dy/dx;
}
// 画下个点
DrawPixel(x,y);
}

PS:一般优化:
为避免小数转整数以及除法运算,由于Sub只是用来进行正负判断,所以可以令Sub = 2dxSub = 2dy-dx,则
相应的DSub = 2dy - 2dx或2dy.

思考1:如果Sub = 0时,会产生取两个点都可以的问题。这个问题还没深入。

Bresenham画线算法的推导相关推荐

  1. java bresenham画直线_图形学笔记: Bresenham画线算法

    图形学课本, 按规矩介绍完矩阵行列式, 第一个算法肯定就是Bresenham画线算法了. 來我们來看看算法 Bresenham是用来画一些不反走样的线段的. 都说了线段肯定有起点和终点, 假设我们: ...

  2. 图形学--(中点画线法+Bresenham画线算法)

    编程环境:codeblocks+EGE库 用到的函数:putpixel(int x1,int y1,int color)  用某种颜色打亮一个坐标点. 这俩种算法都是用来在计算机上画一条直线的,那么我 ...

  3. Bresenham画线算法笔记

    目录 一.DDA算法和中点画线算法的回顾 二.Bresenham画线算法 一.DDA算法和中点画线算法的回顾 1.DDA算法(Digtal Differential Analyzer) 假设两个端点坐 ...

  4. 【计算机图形学】扫面转换算法(DDA算法 中点画线算法 Bresenham画线算法)

    模块1 扫描转换算法 一 实验目的 编写直线.弧线的光栅扫描转换算法,并对线宽与线形的算法加以探讨 用DDA算法.中点画线算法.Bresenham画线算法绘制直线(如果键盘输入数据,给出数据值:如果绘 ...

  5. openGL实现中点画线算法、DDA画线算法,Bresenham画线算法,并进行鼠标键盘的交互

    首先设置变量用于进行鼠标交互和键盘交互: int m = 0; GLdouble m1 =0, m2 = 0; 1.实验入口主函数: //主函数 int main(int argc, char** a ...

  6. bresenham画线算法的最简洁实现

    bresenham画线算法的最简洁实现 具体的bresenham算法可以参考https://www.cs.helsinki.fi/group/goa/mallinnus/lines/bresenh.h ...

  7. JAVA实现中点画线_实验1-中点画线和Bresenham画线算法的实现

    <实验1-中点画线和Bresenham画线算法的实现>由会员分享,可在线阅读,更多相关<实验1-中点画线和Bresenham画线算法的实现(9页珍藏版)>请在人人文库网上搜索. ...

  8. 【OpenGL】画线算法

    文章目录 DDA数值微分线段算法 中点画线法(简) Bresenham画线算法 DDA数值微分线段算法 数值微分法即DDA法(Digital Differential Analyzer),是一种基于微 ...

  9. 图形学画直线c语言,002计算机图形学之直线画线算法

    002计算机图形学之直线画线算法 我们知道直线方程的斜截式是如下的样子: y = kx +b 在显示器上显示直线的话,如果使用如上的方程,每描一个点 需要进行一次浮点乘法,一次浮点加法,和取整操作. ...

最新文章

  1. 聊聊日常开发中,如何对接WebService协议?
  2. golang GOPROXY及GOPRIVATE的设置及作用
  3. 国内知名互联网公司的开源项目
  4. java第二阶段_Java第二阶段总结
  5. sketch-a-net_Adobe XD,Sketch,Figma,InVision-如何在2020年选择最佳设计软件
  6. predict_16x16[i_mode]( p_dst, i_stride )lowres
  7. 使用 pyinstaller 打包 py 文件成 exe 程序
  8. 用canvas实现手写签名功能
  9. AMD平台下在Windows虚拟机中安装Mac10.8.3的注意事项
  10. redis配置文件redis.conf详细说明
  11. Python基础--01
  12. pytorch中模型结构图的可视化
  13. win10 计算机 桌面图标不见了,win10系统桌面图标没了的解决方法
  14. SMB/CIFS--NetBOIS/Browser/NBNS 协议
  15. 把咖啡这桩生意放进独立站,总共分几步?(上)
  16. w7电脑蓝屏怎么解决_win7电脑蓝屏怎么解决|win7系统蓝屏修复方法
  17. python打开jpg_python如何读jpg文件
  18. 走向面试之数据库基础:一、你必知必会的SQL语句练习-Part 2
  19. matlab导入word数据,如何将Excel数据导入MATLAB中?/excel数据导入word模板
  20. 《数据解构》HashMap源码解读

热门文章

  1. xshell通过密钥连接服务器(阿里云、腾讯云等)
  2. 中南大学941计算机网络考试大纲,中南大学计算机网络问答题
  3. 弱电包含在计算机专业,弱电工程包含哪些内容
  4. 汽车加油问题--贪心算法(算法设计与分析)
  5. 企业如何选择合适的SaaS软件?
  6. 计算机说课稿模板小学数学,优秀小学数学专用说课模板
  7. 李兴华java视频在线观看_李兴华Java开发实战经典视频教程_IT教程网
  8. JS的传递数据不刷新页面的应用
  9. 零起点学VB做外挂(一)
  10. 华为S2300 配置