文章目录

  • 前言
  • Bresenham 画圆算法原理
    • 两个近似
    • 构造判别式
    • 圆与网格点的关系
      • 关系由来
      • 关系含义
    • pip_ipi​ 递推
    • 画圆
    • 程序伪码
  • 圆与网格点的关系图示

前言

首先简要介绍一下生成圆的方法:

  1. 直接利用圆的方程生成圆
  2. 利用圆的对称性生成圆

方法一由于会涉及到浮点运算等因素,不采取该方案。
ps. 这部分想要知道为什么可以参考 计算机图形学 圆及椭圆的扫描转换_百度文库 前面一点。
方法二的原理如下图,利用圆的对称性,我们只需要对一个八分圆进行扫描转换。

在这里我们不妨选择第一象限上斜率绝对值小于1的那八分圆进行扫描转换,以及假设圆心为 (0, 0) 。也就是下图。
友情提示:圆在某点的斜率是该点处切线斜率。圆心不在 (0, 0) 处的点可以通过平移得到。

Bresenham 画圆算法原理

如下图,在 0≤x≤y 的 1/8 圆周上,像素坐标 x 值单调增加,y 值单调减少。
设第 i 步已确定(xi,yi)(x_i, y_i)(xi​,yi​)是要画圆上的像素点,看第 i+1 步像素点(xi+1,yi+1)(x_{i+1}, y_{i+1})(xi+1​,yi+1​)应如何确定。下一个像素点只能是H(xi+1,yi)H(x_i+1, y_i)H(xi​+1,yi​)或者D(xi+1,yi−1)D(x_i+1,y_i-1)D(xi​+1,yi​−1)中的一个 。

具体选哪个就得看 dH和dDd_H 和 d_DdH​和dD​ 二者的比较了:

  1. dHd_HdH​ 更小,下一个像素点就选 H(xi+1,yi)H(x_i+1, y_i)H(xi​+1,yi​)
  2. dDd_DdD​ 更小,下一个像素点就选 D(xi+1,yi−1)D(x_i+1,y_i-1)D(xi​+1,yi​−1)
  3. 一样大,选哪个都行。

比较方法就是做差:dH−dDd_H - d_DdH​−dD​,然后将结果与0进行比较。

那么问题是 dH和dDd_H 和 d_DdH​和dD​ 二者的值是怎么求得呢?这里就涉及到一个近似:

两个近似

近似方法:
将 CH 近似为 dHd_HdH​
将 DB 近似为 dDd_DdD​

由大图显而易见可以知道 CH 和 DB 的值:
CH=OH−OC=(xi+1)2+yi2−R=dHCH = OH - OC = \sqrt{(x_i+1)^2 + y_i^2} - R = d_HCH=OH−OC=(xi​+1)2+yi2​​−R=dH​
DH=OB−OD=R−(xi+1)2+(yi−1)2=dDDH = OB - OD = R - \sqrt{(x_i+1)^2 + (y_i-1)^2} = d_DDH=OB−OD=R−(xi​+1)2+(yi​−1)2​=dD​

这里由于涉及到了根号运算,因此又做了一个近似:
dH=(xi+1)2+yi2−R2d_H = (x_i+1)^2 + y_i^2 - R^2dH​=(xi​+1)2+yi2​−R2
dD=R2−(xi+1)2−(yi−1)2d_D = R^2 - (x_i+1)^2 - (y_i-1)^2dD​=R2−(xi​+1)2−(yi​−1)2

构造判别式

我们不妨构造如下判别式
pi=dH−dDp_i = d_H - d_Dpi​=dH​−dD​
=(xi+1)2+yi2−R2−(R2−(xi+1)2+(yi−1)2)\space\space\space\space= (x_i+1)^2 + y_i^2 - R^2 - (R^2 - (x_i+1)^2 + (y_i-1)^2)    =(xi​+1)2+yi2​−R2−(R2−(xi​+1)2+(yi​−1)2)
=2(xi+1)2+2yi2−2yi−2R2+1\space\space\space\space= 2(x_i+1)^2 + 2y_i^2-2y_i\textcolor{red}{-2R^2+1}    =2(xi​+1)2+2yi2​−2yi​−2R2+1

圆与网格点的关系

关系由来

圆与网格点有且仅有上述5种关系,情况分别如上:

其中的BCEF均为该网格上的中点。

首先,我们得再次强调的一点是,在 0≤x≤y 的 1/8 圆周上的每点的斜率绝对值都小于1。即它们与 x 轴负方向的倾角都不能超过图中的 FE 线段。

由于,我们现在点亮的点是 P(xi,yi)P(x_i, y_i)P(xi​,yi​) ,所以圆与 x=1 的交点应该在 BF 之间。由于此段圆弧的斜率均小于1,因此圆与 x=2 的交点应该在 CE 之间,由此上上图中的 5 条圆弧都有了解释:
圆弧1:圆与 x=1 的交点在 BP 间,且该圆斜率变化很小(半径很大)
圆弧4,5:我个人认为是在接近 y=x 这条直线处的网格可以产生这种情况

关系含义


构造判别式:pi=dH−dDp_i = d_H-d_Dpi​=dH​−dD​

  1. 精确圆弧是③,则dH>0和dD>0d_H >0和d_D>0dH​>0和dD​>0
    若pi<0,即dH<dD应选H点若p_i<0,即d_H <d_D应选H点若pi​<0,即dH​<dD​应选H点
    若pi≥0,即dH≥dD应选D点若p_i≥0,即d_H ≥d_D应选D点若pi​≥0,即dH​≥dD​应选D点
  2. 若精确圆弧是①或②,显然H是应选择点,而此时dH≤0,dD>0d_H ≤0,d_D>0dH​≤0,dD​>0,必有pi<0p_i<0pi​<0。
  3. 若精确圆弧是④或⑤,显然D是应选择点,而此时dH>0,dD≤0d_H >0,d_D≤0dH​>0,dD​≤0,必有pi>0p_i>0pi​>0。

得出结论:pip_ipi​ 做判别量,pi<0p_i<0pi​<0 时,选H点为下一个像素点,pi≥0p_i≥0pi​≥0 时,选D点为下一个像素点。

pip_ipi​ 递推

因为 pip_ipi​ 代表此次选择哪个点的判别式,如果我们知道下一次选点的判别式和其关系就可以节省很多思考。所以我们要从 pip_ipi​ 计算 pi+1p_{i+1}pi+1​。
ps. 对 pi+1p_{i+1}pi+1​ 数学意义的解释:此次点亮的点我们称做(xi,yi)(x_i, y_i)(xi​,yi​),下一次点亮的点我们就称做 (xi+1,yi+1)(x_{i+1}, y_{i+1})(xi+1​,yi+1​)。 xi+1x_{i+1}xi+1​ 的值和 xix_ixi​ 是有递推关系的(xi+1=xi+1x_{i+1}=x_i+1xi+1​=xi​+1 ,见关系由来下的图)。而此次我们将判断点亮哪个点的判别式记作 pip_ipi​,类似的,下次判断点亮哪个点的判别式我们就记作 pi+1p_{i+1}pi+1​
pi=dH−dDp_i = d_H - d_Dpi​=dH​−dD​
=(xi+1)2+yi2−R2−(R2−(xi+1)2+(yi−1)2)\space\space\space\space= (x_i+1)^2 + y_i^2 - R^2 - (R^2 - (x_i+1)^2 + (y_i-1)^2)    =(xi​+1)2+yi2​−R2−(R2−(xi​+1)2+(yi​−1)2)
=2(xi+1)2+2yi2−2yi−2R2+1\space\space\space\space= 2(x_i+1)^2 + 2y_i^2-2y_i\textcolor{red}{-2R^2+1}    =2(xi​+1)2+2yi2​−2yi​−2R2+1

pi+1=2(xi+1+1)2+2yi+12−2yi+1−2R2+1p_{i+1}=2(x_{i+1}+1)^2 + 2y_{i+1}^2-2y_{i+1}\textcolor{red}{-2R^2+1}pi+1​=2(xi+1​+1)2+2yi+12​−2yi+1​−2R2+1
pi+1−pi=4xi+6+2(yi+12−yi2−yi+1+yi)p_{i+1}-p_i=4x_i+6+2(y_{i+1}^2-y_i^2-y_{i+1}+y_i)pi+1​−pi​=4xi​+6+2(yi+12​−yi2​−yi+1​+yi​)

  1. 当 pi≥0p_i≥0pi​≥0 时,应选D点,此时 D 点的 y 坐标和 P 的 y 坐标的关系是 yi+1=yi−1y_{i+1} = y_i - 1yi+1​=yi​−1,带入上式有:
    pi+1=pi+4(xi−yi)+10p_{i+1}=p_i+4(x_i-y_i)+10pi+1​=pi​+4(xi​−yi​)+10
  2. 当 pi<0p_i<0pi​<0 时,应选H点,此时 H 点的 y 坐标和 P 的 y 坐标的关系是 yi+1=yiy_{i+1} = y_iyi+1​=yi​,带入上式有:
    pi+1=pi+4xi+6p_{i+1}=p_i+4x_i+6pi+1​=pi​+4xi​+6

画圆

画圆的起始点是(0, R),即 x1=0,y1=Rx_1=0, y_1=Rx1​=0,y1​=R,带入前式。即令 i=1 ,就得到:
pi=3−2Rp_i=3-2Rpi​=3−2R
剩下的递推就行。

程序伪码

void BresenhamCircle(int R){     int x,y,p;x=0;  y=R;p=3-2*R;for(;x<=y;x++){       SetPixel(x,y);if(p>=0){p+=4*(x-y)+10;y--;}else {p+=4*x+6;}}
}


根据对称性,只需修改语句 SetPixel(x,y),画八个对称的点,就可以画出全部圆周。若加一个平移,就可以画出圆心在任意位置的圆周

圆与网格点的关系图示

情况一:x2+y2=10000x^2+y^2=10000x2+y2=10000
其中 142+992=999714^2+99^2=9997142+992=9997

情况五:x2+y2=10000x^2+y^2=10000x2+y2=10000,那条横线是 y=77.5
其中 652+762=1000165^2+76^2=10001652+762=10001

时间有限,姑且只画这俩。

Bresenham 画圆算法原理相关推荐

  1. 中点Bresenham画圆算法|MFC|计算机图形学

    中点Bresenham画圆算法|MFC|计算机图形学 Bresenham中点画圆算法 计算机图形学-基本图元的生成-圆 基于学习直线的生成算法后,又展开了圆.椭圆的讲解: 此次试验是简单的MFC应用, ...

  2. 【计算机图形学】小白谈计算机图形学(二)画圆篇之中点画圆法,Bresenham画圆算法,椭圆实操,线型处理详解

    小白谈计算机图形学(二)画圆篇之中点画圆法,Bresenham画圆算法,椭圆实操,线型处理详解 引言 如何画圆 基本思想 中点画圆法 中点画圆基本思路 中点画圆改进 Bresenham画圆算法 Bre ...

  3. Bresenham画圆算法

    Bresenham 画圆算法适合于生成整圆,它使用8路对称法,只计算出90°~45°内的点,移动方向为+x,-y. 递推公式: 完整代码: 加上Sleep函数,减慢画圆速度,以便观察画圆过程. #in ...

  4. 计算机图形学实习教程之基本图形的生成(直线DDA算法,直线中点算法,Bresenham画圆算法),利用C#实现,附源码

    环境:Win10+Visual Studio 2022 Community 在本次实验中需要用到上一篇文章实验内容的代码及环境,详情请见:传送门 目录 一.实验目的 二.实验过程 1.生成直线的DDA ...

  5. bresenham算法画圆c语言,bresenham画圆算法

    中点画圆算法在一个方向上取单位间隔,在另一个方向的取值由两种可能取值的中点离圆的远近而定.实际处理中,用决策变量的符号来确定象素点的选择,因此算法效率较高. 设要显示圆的圆心在原点(0,0),半径为R ...

  6. C语言——中点画圆算法和Bresenham画圆算法(easyx图形库)

    一.中点画圆法 首先是中点画圆法,考虑圆心在原点,半径为R的圆在第一象限内的八分之一圆弧,从点(0, R)到点(R/ , R/ )顺时针方向确定这段圆弧.假定某点Pi(xi, yi)已经是该圆弧上最接 ...

  7. 【计算机图形学】中点画圆算法和Bresenham画圆算法

    在平面解析几何中,圆的方程可以描述为(x – x0)2 + (y – y0)2 = R2,其中(x0, y0)是圆心坐标,R是圆的半径,特别的,当(x0, y0)就是坐标中心点时,圆方程可以简化为x2 ...

  8. python3画圆、直线_Bresenham直线算法与画圆算法

    在我们内部开发使用的一个工具中,我们需要几乎从 0 开始实现一个高效的二维图像渲染引擎.比较幸运的是,我们只需要画直线.圆以及矩形,其中比较复杂的是画直线和圆.画直线和圆已经有非常多的成熟的算法了,我 ...

  9. java用中点画圆法_Bresenham画圆算法 与中点画圆法

    Bresenham画圆算法 不失一般性,假设圆的圆心位于坐标原点(如果圆心不在原点,可以通过坐标平移使其与原点重合),半径为R.以原点为圆心的圆C有四条对称轴:x = 0, y = 0, x = y和 ...

最新文章

  1. layui如何集成文件服务器,layui使用upload组件实现文件上传功能
  2. Lnc2cancer 3.0,lncRNAs和circRNAs数据更新及分析工具使用指南
  3. cat查看tomcat日志 linux_方法篇:tomcat日志切割和定期删除
  4. gitlab 修改HTTP连接方式中的IP和端口
  5. SQLSERVER复制订阅中的数据库版本选择
  6. 解决IDEA中自动生成返回值带final修饰的问题
  7. 前用户sudo免密码
  8. 网络创业:网站盈利模式分析分类
  9. @Results用法总结
  10. 命令与征服3 凯恩之怒
  11. 计算机音乐谱子十年,十年曲谱钢琴曲_十年 钢琴谱
  12. 单片机控制电路的多图纸原理图和层次式设计
  13. 实现带头结点单链表的就地逆置问题。
  14. matlab调整视频播放速度,会声会影如果调整视频播放速度
  15. python psutil 进程cpu_python 模块psutil获取进程信息
  16. react-router v4 路由改变页面不刷新
  17. FCPX插件 66种手绘漫画MG动画元素包 Comic Pop 破解版
  18. SAP-ABAP-SQL语句中CAST字段类型转换示例,CONCAT连接示例,SUBSTRING截断示例
  19. JAVA核心技术,卷1
  20. python编程之旅 random随机库 第一课 制作简单的随机数程序

热门文章

  1. 大学计算机实验基础第二版,大学计算机基础实验指导(第2版)
  2. 如何制作 Sketch 插件
  3. PPT文件带有打开密码怎么解决
  4. 微信成语接龙小程序|微擎框架|带流量主|前端+后端完整源码
  5. Unity制作AR图片和视频展示
  6. 学计算机专业可以做施工员吗,大龄转行做工程施工员,学起吃力吗?
  7. T-Code (Controlling)
  8. C语言从一段字符串中提取IP地址的方法
  9. 谷歌浏览器chrome 语言设置为英文
  10. 如何将GMS功能移植到Android系统中