最近作业在做 graphics driver 涉及到 Bresenham 画线以及画圆算法,以防自己忘记了总结一些知识点以及源码。

所有代码的输入参数类型都是 unsinged int

  • Bresenham 直线算法

在给出直线两个端点(x1, y1) 和 (x2, y2) 的情况下,选取 (x1, y1) 作为起始点, 依次确认相应的像素点。选取哪个端点作为起点是没有关系的,因为线段并不存在方向这一说,只是和斜率有关系,下面会提到。

以点 (xi, yi) 为例,以 y 为步进单位, (xi, yi) 的下一个像素点为 (xi+1, yi+1) 和 (xi+1, yi) 中的一个点,那么为了确认到底应该选哪一个点,这时就要比较垂直距离 d1 和 d2 的关系。设直线的方程为 y = kx + b,其中 k=Δy/Δx, Δy = abs(y2 - y1), Δx = abs(x2 - x1)。此时

, 

接下来可以得到

在上面这个表达式中,可以发现我们涉及到了除法运算,为了消除除法运算可能引入的误差,在等式两边同时乘 Δx, 并命名为一个新的变量

其中c是最终化简得到的总的常数。此时 pi 和(d1 - d2) 同号,我们可以根据 pi 的正负来判断下一个像素点的位置:

当 pi > 0 时, d1 > d2,, 

当 pi <= 0 时,d1 <= d2,, 

由于直线起点为 (x1, y1), 那么将起点坐标带入 p 的表达式后可以得出 p1 的值:

, 其中 , 化简得 

以上为 Bresenham 算法的基本思想,由于我们只讨论了步进单位为 y 的情况,也就是说以上情况中我们能得到的直线最大斜率为 1(也就是说上述过程都是在讨论 Δx > Δy 的情况)。那么对于直线斜率小于等于 1 的情况, 只需要把步进单位改成 x 就可以了。

以下为源代码:

可以直接定义 void 类型,不用返回值。

  • Bresenham 画圆算法

圆形算法和直线算法思想差不多,都是根据前一个像素点来选取后一个像素点的位置。由于圆的对称性,在得到圆上的一个点的同时,相当于我们同时得到了圆上互相对称的八个点,可以看下图理解一下 (坐标轴我忘画了嘻嘻嘻)

和直线算法同理,在点 (xi, yi) 的基础上,在 (xi+1, yi+1) 和(xi+1, yi) 中确定下一个像素点,那么按理说还是应该比较 d1 和 d2 的大小,但是这俩值并不好求(涉及到浮点数运算 blablabla),所以在这里做一个近似,令 d1 = d3 = |AC|, d2 = d4 = |BD|, , 。 同样的引入一个变量 p 来表示差值 ,情况如下:

当 pi > 0 时,选取点 (xi+1, yi+1), 

当 pi <= 0 时, 选取点 (xi+1, yi), 

将起始点设为 (0, r),

根据圆的八分对称性,先设置八个部分的坐标值(圆心可以任意选取), 这部分可以单独写一个函数也可以和画圆合并。代码如下:

如果想要对圆进行填充,可以选取外接正方形,判断正方形内的像素点是否在圆内来填充,也可以用 Bresenham 法画 n 个圆来填充, 由于我用第二种方法填充有部分像素点填不满,所以就先放第一种方法的代码:

转载于:https://www.cnblogs.com/molly77/p/10556259.html

Bresenham 算法画线 画圆相关推荐

  1. 中点Bresenham算法光栅化画椭圆(四分法)

    void Bresenham_Ellipse(CDC *pDC, int ox, int oy, int a, int b)//圆心x,圆心y,横长,纵长 {float d = b*b + a*a*( ...

  2. 圆的Bresenham算法C语言代码,圆的Bresenham算法的opengL实现

    源代码实现如下: // Bresenham_circile.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include #includ ...

  3. MFC初学笔记之画线画笔画刷

    学习了WINdows程序的框架之后本来是要弄opengl的,后来想想还要在opengl上面添加按钮label什么的与用户交换,后来有考虑学了QT,感觉封装的太....又在学MFC,个人感觉用MFC 比 ...

  4. IOS的画线方法 CGContext

    使用context画线制作的手表 源码下载地址:http://download.csdn.net/detail/q562679764/9367221 context画线 画直线 //获取view上下文 ...

  5. Matlab画线实例图

    1 plot画线 直线: 设置线宽和颜色: 黄色,8像素宽: 直线,黄色: 2 line 画线 画的是坐标(1,3)到(2,4)的一条线: 设置线型和颜色: 3 数学曲线 另一个:

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

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

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

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

  8. Bresenham画线算法笔记

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

  9. Bresenham画线算法的推导

    转自:https://www.cnblogs.com/soroman/archive/2006/07/27/509602.html 以前看到Bresenham画线算法,直接拿来用,没有去推导它,近日, ...

最新文章

  1. 阿里云https认证
  2. 浏览器内核Trident/Gecko/WebKit/Presto
  3. nginx配置location匹配顺序总结
  4. 问题1-2:能否说:“电路交换和面向连接是等同的,而分组交换和无连接是等同的”? 答:不行。这在概念上是很不一样的。这点可举例说明如下。...
  5. 计算机机房规范管理,计算机中心机房建设及管理规范.doc
  6. template模板的使用方法
  7. LVM和raid结合使用
  8. 深入浅出: Java回调机制(异步)
  9. 两个半月!出差终于结束啦
  10. jvm虚拟机组成部分讲解、jvm虚拟机参数使用讲解并发编程框架篇
  11. uni-app 微信小程序自定义radio样式
  12. 覆盖与隐藏的区别 (一个列子)
  13. PAIP.MYSQL 1045 Access denied for user 'XXXX'@'loca 的解决.txt
  14. 幅频特性曲线的绘制(2)
  15. matlab如何批量去背景,ImageJ怎么消除背景 批量去背景教程
  16. 淘宝API店铺所有商品接口价格、标题、销量参数调用示例
  17. android怎样开启root权限管理,手机怎样开启root权限(最新安卓手机一键root教程)...
  18. 网络信息安全知识框架
  19. qt osg 多点触摸
  20. 王者荣耀交流协会-小组互评Alpha版本

热门文章

  1. javaweb成长之路:struts2的探索(一)
  2. 教你在Linux下构建主、从域名服务器!
  3. 赛门铁克公布Q3财报 亏损68亿美元
  4. CHIL-SQL-FIRST() 函数
  5. idea下的调试配置
  6. urllib2介绍(转)
  7. Web服务器启动端口冲突问题
  8. 隐藏和伪装端口banner
  9. 精确记算程序的运行时间或者某段代码的运行时间
  10. Linux I2C子系统分析-I2C总线驱动