计算机图形学--2种圆绘制算法原理及代码实现

本文详细解析了MidPoint和Bresenham算法在绘制圆的过程中,如何利用圆的几何特性,通过递推和决策优化,分别实现高效地顺时针绘制八分之一圆弧进而完成整圆。两种算法的原理、代码实现及其在计算机图形学中的应用都被深入剖析。
摘要由CSDN通过智能技术生成

目录

圆的几何特性分析

MidPoint画圆算法

原理:

代码实现:

Bresenham画圆算法

原理:

代码实现:


圆的几何特性分析

        圆是中心对称图形,具有以下几何特性:
        1>对于一个圆心在原点的圆形对象,圆上一个点,我们可以根据x=y、x=0、y=0三条对轴,将其不断对称产生圆上8个点,如下图利用(xi, yi)可产生圆上标注的8个点.
        2>同样的,对于一个圆的1/8圆弧来讲,可以根据x=y、x=0、y=0三条对轴,将其不断对称产生整圆,如下图利用一象限y轴与y=x直线之间的8分之圆可以对称得到整圆.
        3>利用八分之圆对称得到整圆的方法本质上是利用八分之圆上所有点对称得到整圆的过程。

        下面给出的圆的绘制算法都是基于以上对圆的几何特性的认识展开的。
        说明:对于圆我们可以首先考虑当圆心在坐标原点的情况,然后再根据圆心位置将圆上坐标进行平移,得到圆的实际位置。下面我们的考虑都是基于圆心在坐标原点进行分析。实际算法中进行简单变化即可。

MidPoint画圆算法

原理:

        MidPoint画圆算法的思想与中点画直线算法的思想大致一致,在前一已知点位置的基础上,选择下一绘制点可能像素位置中靠近圆像素进行绘制的一种算法。

      我们考虑第一象限y轴与直线y=x之间的八分之圆的顺时针绘制方式。对于这一部分的点来讲,假设在某点(xpos, ypos)确定的情况下,那么我们绘制的下一个像素点位置应当在(xpos+1, ypos)与(xpos+1, ypos-1)之间做选择。决策方式取决于这两点中点(xpos+1, ypos-0.5)与圆的位置关系,具体来讲,就是点(xpos+1, ypos-0.5)在圆的外面时,点(xpos+1, ypos-1)据圆上点更近,选择该点;点(xpos+1, ypos-0.5)在圆的内部时,点(xpos+1, ypos)据圆上点更近,选择该点。利用圆半径,我们可以获知圆方程为x*x+y*y-R*R=0,令d=F(x, y)=x*x+y*y-R*R,则当F(xi, yi)>0时,点(xi, yi)在圆的外面;当F(xi, yi)<0时,点(xi, yi)在圆的外面;当F(xi, yi)=0时,点(xi, yi)在圆上。根据以上分析,我们可以由点(0,radius)出发,依次选择这个八分圆内的绘制点,并将这些点以及对称产生的另外七个点进行绘制,完成整圆的绘制。

        对于上述过程来讲,每次进行乘法计算时间效率不高,考虑递推过程中d的递推方式简化计算。有以下结论成立:
1>首先,对于d的初值我们易得为1.25-R。由于我们所涉及的都是整数运算,1.25-R在正负性上与1-R等价,为简化计算,可认为d0=1-R。
2>假设我们现在确定绘制了(xpos, ypos)点,并对d进行一定变化后(此时d=F(xpos+1, ypos+0.5)),d<0,那么下一个点选择(xpos+1, ypos),并且我们要计算的下一个中点位置为:F(xpos+2, ypos-0.5)=(xpos+2)^{2}+(ypos-0.5)^{2}-R^{2} =(xpos+1)^{2}+(ypos-0.5)^{2}-R^{2}+2*xpos+3 =d+(xpos<<1)+3
得到d的变化deta1=(xpos<<1)+3。
3>假设我们现在确定绘制了(xpos, ypos)点,并对d进行一定变化后,d>=0,那么下一个点选择(xpos+1, ypos-1),并且我们要计算的下一个中点位置为:F(xpos+2, ypos-1.5)=(xpos+2)^{2}+(ypos-1.5)^{2}-R^{2}=(xpos+1)^{2}+(ypos-0.5)^{2}-R^{2}+2*xpos+3-2*ypos+2=d+((xpos-ypos)<<1)+5
得到d的变化deta2=((xpos-ypos)<<1)+5。
        综合以上结论,我们可以得到d的递推方式。

代码实现:

void MidPointCircle(const pair<int, int>& center, int radius, unsigned long color)
{
	int xbase = 0, ybase = radius;
	//首先进行四分圆界限上点的绘制,原因:在下面的绘制算法中,这四个点会被忽略。
	dc.SetPixel(center.first, center.second + radius, color);
	dc.SetPixel(center.first, center.second - radius, color);
	dc.SetPixel(center.first + radius, center.second, color);
	dc.SetPixel(center.first - radius, center.second, color);
	int d = 1 - radius;
	while (ybase >= xbase)
	{
		if (d < 0)
		{
			xbase++;
			d = d + (xbase << 1) + 3;
		}
		else
		{
			xbase++, ybase--;
			d = d + ((xbase - ybase) << 1) + 5;
		}
		dc.SetPixel(center.first + xbase, center.second + ybase, color);
		dc.SetPixel(center.first - xbase, center.second + ybase, color);
		dc.SetPixel(center.first + xbase, center.second - ybase, color);
		dc.SetPixel(center.first - xbase, center.second - ybase, color);
		dc.SetPixel(center.first + ybase, center.second + xbase, color);
		dc.SetPixel(center.first - ybase, center.second + xbase, color);
		dc.SetPixel(center.first + ybase, center.second - xbase, color);			
        dc.SetPixel(center.first - ybase, center.second - xbase, color);		              
	}
}

Bresenham画圆算法

原理:

        Bresenham画圆算法中我们对第一象限的四分之圆进行考虑(同样是顺时针方向进行绘制)。那么对于一个我们已经确定的点(xpos, ypos)来讲,下一个被绘制的像素点可能是(xpos+1, ypos)、(xpos+1, ypos-1)或(xpos, ypos-1)中的一个,实际圆弧存在5种情况,如下图(xi, yi)以及点H、D、V点所示:

         对于下一绘制点的决策同样取决于哪个点与圆的距离最近。令d=F(x, y)=x*x+y*y-R*R,则当F(xi, yi)>0时,点(xi, yi)在圆的外面;当F(xi, yi)<0时,点(xi, yi)在圆的外面;当F(xi, yi)=0时,点(xi, yi)在圆上。我们可以首先判断D点与圆的位置关系。假设D点在圆上(即F(xpos+1, ypos-1)=0),那么我们可以直接绘制D点,然后考察后面的点;假设D点在圆内部(即F(xpos+1, ypos-1)<0),那么我们需要进一步在H、D点之间决策哪个点更加接近圆,然后进行该点的绘制。假设D点在圆外部(即F(xpos+1, ypos-1)>0),那么我们需要进一步在D、V点之间决策哪个点更加接近圆,然后进行该点的绘制。在H、D之间的决策可以通过|F(H)|-|F(D)|值的正负性进行判断,该值为正说明D点距圆更近,故而对D点进行绘制,否则证明H点距圆更近,对H点进行绘制。在V、D之间的决策同理。

        对于上述过程,同样存在每一点的决策过程涉及多次乘法运算,时间效率低的问题,故考虑决策以及d的递推过程。存在以下结论:
1>对于d的初值,易得为F(1, R-1)=2*(1-R)=(1-R)<<1。
2>假设我们现在确定绘制了(xpos, ypos)点,当前d为F(xpos+1, ypos-1),当d<0时,我们需要在(xpos+1, ypos)与(xpos+1, ypos-1)之间进行选择,选择依据为|F(xpos+1, ypos)|-|F(xpos+1, ypos-1)|的正负。对于这个表达式我们可以化简为:
judgeHD\\=|F(xpos+1, ypos)|-|F(xpos+1, ypos-1)|\\=F(xpos+1, ypos)+F(xpos+1, ypos-1)\\=(xpos+1)^{2}+(ypos)^{2}-R^{2}+d\\=2d+2*ypos-1\\=((d+ypos)<<1)-1{\color{Red} }{\color{Emerald} }
judgeHD>0时下一个点选择为(xpos+1, ypos-1),否则下一个点选择为(xpos+1, ypos)。
3>假设我们现在确定绘制了(xpos, ypos)点,当前d为F(xpos+1, ypos-1),当d>0时,我们需要在(xpos, ypos-1)与(xpos+1, ypos-1)之间进行选择,选择依据为|F(xpos+1, ypos-1)|-|F(xpos, ypos-1)|的正负。对于这个表达式我们可以化简为:
judgeDV\\=|F(xpos+1, ypos-1)|-|F(xpos, ypos-1)|\\=F(xpos+1, ypos-1)+F(xpos, ypos-1)\\=d+(xpos)^{2}+(ypos-1)^{2}-R^{2}\\=2*d-2*xpos-1\\=((d-xpos)<<1)-1
judgeDV>0时下一个点选择为(xpos, ypos-1),否则下一个点选择为(xpos+1, ypos-1)。
4>假设我们现在确定绘制了(xpos, ypos)点,当前d为F(xpos+1, ypos-1),当d=0时,下一个点选择为(xpos+1, ypos-1)。
5>当下一个点选择为(xpos+1, ypos-1)时,我们下一次需要计算F(xpos+2, ypos-2),有:
F(xpos+2, ypos-2)\\=(xpos+2)^{2}+(ypos-2)^{2}-R^{2}\\=d+2*xpos+3-2ypos+3\\=d+((xpos-ypos+3)<<1)
故d的变化量deat1为((xpos-ypos+3)<<1)。
6>当下一个点选择为(xpos+1, ypos)时,我们下一次需要计算F(xpos+2, ypos-1),有:
F(xpos+2, ypos-1)=(xpos+2)^{2}+(ypos-1)^{2}-R^{2}=d+2*xpos+3
故d的变化量deat2为(xpos<<1)+3。
7>当下一个点选择为(xpos, ypos-1)时,我们下一次需要计算F(xpos+1, ypos-2),有:
F(xpos+1, ypos-2)=(xpos+1)^{2}+(ypos-2)^{2}-R^{2}=d-2*ypos+3
故d的变化量deat3为-(ypos<<1)+3。
        综合以上结论,我们可以得到决策以及d的递推过程。

代码实现:

void BresenhamCircle(const pair<int, int>& center, int radius, unsigned long color)
{
	int xbase = 0, ybase = radius, pos=0;
	int d = (1 - radius) << 1;
	while (ybase >= 0)
	{
		if (d > 0)
		{
			if (((d - xbase) << 1) - 1 <= 0) d = d + ((xbase - ybase + 3) << 1), xbase++, ybase--;
			else d = d - (ybase << 1) + 3, ybase--;
		}
		else if (d < 0)
		{
			if (((d + ybase) << 1) - 1 <= 0) d = d + (xbase << 1) + 3, xbase++;
			else d = d + ((xbase - ybase + 3) << 1), xbase++, ybase--;
		}
		else d = d + ((xbase - ybase + 3) << 1), xbase++, ybase--;
		dc.SetPixel(center.first + xbase, center.second + ybase, color);
		dc.SetPixel(center.first - xbase, center.second + ybase, color);
		dc.SetPixel(center.first + xbase, center.second - ybase, color);
		dc.SetPixel(center.first - xbase, center.second - ybase, color);
	}
}

  • 12
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《计算机图形学原理算法教程(visual.cpp版)第二版》目录如下: 第一章 绪论 1.1 计算机图形学概述 1.1.1 计算机图形学发展历程 1.1.2 计算机图形学的应用领域 1.2 图形系统概述 1.2.1 图形系统的组成 1.2.2 图形系统的分类 1.3 图形学基本概念 1.3.1 图像与图形的区别 1.3.2 像素和分辨率 1.3.3 图形的表示方式 1.4 计算机图形学的基本操作 1.4.1 点、线和面的生成 1.4.2 变换和投影 1.4.3 光照和着色 第二章 图形数据的存储与表示 2.1 位图图形的表示 2.1.1 位图图形的基本概念 2.1.2 位图图形的存储格式 2.2 矢量图形的表示 2.2.1 矢量图形的基本概念 2.2.2 矢量图形的存储格式 2.3 图形数据的压缩与解压缩 2.3.1 图像压缩的基本原理 2.3.2 常用的图像压缩算法 第三章 二维图形的生成与变换 3.1 线段的生成与绘制 3.1.1 线段的基本生成算法 3.1.2 线段的绘制算法 3.2 多边形的扫描转换 3.2.1 多边形的填充算法 3.2.2 多边形的裁剪算法 3.3 二维图形的变换 3.3.1 平移、旋转和缩放 3.3.2 裁剪和反走样 第四章 三维图形的生成与变换 4.1 三维图形的生成和显示 4.1.1 点的生成与显示 4.1.2 线段的生成与显示 4.1.3 多边形的生成与显示 4.2 三维物体的变换 4.2.1 三维物体的平移、旋转和缩放 4.2.2 三维物体的投影和裁剪 4.3 隐线消除和填充 4.3.1 隐线消除算法 4.3.2 隐面消除算法 4.3.3 物体的填充算法 第五章 光照与着色 5.1 光的基本原理与模型 5.1.1 光的微粒特性 5.1.2 光的传播模型 5.1.3 光源的分类与属性 5.2 表面的光照模型 5.2.1 平均光照模型 5.2.2 高光反射模型 5.2.3 着色模型的应用 第六章 特殊效果与动画 6.1 图形的扭曲与变形 6.1.1 图形的弯曲与纹理映射 6.1.2 图形的拉伸与卷轴效果 6.2 图形的动画与交互 6.2.1 图形的平移和旋转动画 6.2.2 用户交互与响应 第七章 计算机图形学应用实例 7.1 计算机辅助设计(CAD)的应用 7.2 图像处理与识别的应用 7.3 游戏开发中的图形学应用 7.4 虚拟现实与增强现实的应用 附录A 几何代数及矩阵运算基础 附录B 常用数学函数库的使用 附录C 图形学软件开发的实践技巧 《计算机图形学原理算法教程(visual.cpp版)第二版》通过详细介绍计算机图形学原理算法和应用实例,帮助读者全面了解计算机图形学的基础知识,并学习如何利用visual.cpp进行图形的生成、变换、光照和特殊效果等操作。 ### 回答2: 《计算机图形学原理算法教程(visual.cpp版)第二版》的目录包括以下章节: 第一章:引言 这一章介绍了计算机图形学的基本概念和发展历程,以及本书的编写目的和结构。 第二章:图形学基础 这一章介绍了图形学的基本原理,包括坐标系统、坐标变换、颜色模型以及图形显示的基本概念。 第三章:2D图形处理 这一章讲解了二维图形的处理方法,包括直线段生成算法、多边形填充算法以及曲线生成算法等。 第四章:3D图形处理 这一章介绍了三维图形的处理方法,包括三维变换、投影、光照和着色等技术。 第五章:图形图像的存储和显示 这一章讨论了图形图像在计算机中的存储和显示方法,包括位图和矢量图的表示方式以及图形文件格式等。 第六章:可视化技术 这一章介绍了计算机图形学在可视化领域的应用,包括模拟真实场景、虚拟现实和数据可视化等方面的内容。 第七章:图形处理硬件 这一章讨论了图形处理的硬件实现,包括图形显示器、图形加速卡以及图形处理单元等。 第八章:图形学应用 这一章介绍了计算机图形学在各个领域的具体应用,包括游戏开发、电影制作、工程设计等方面的案例分析。 第九章:计算机图形学的发展趋势 这一章展望了计算机图形学的未来发展方向,包括虚拟现实、增强现实和深度学习等技术的应用。 附录:附录A-参考文献 本附录列出了相关领域的经典文献和参考书目,供读者进一步学习和研究使用。 通过本书的学习,读者可以全面了解计算机图形学的基本原理算法,了解其在各个领域的应用,并了解到该领域的发展趋势。本书同时提供了大量的示例代码和实验项目,有助于读者深入理解和运用所学知识。 ### 回答3: 第二版的《计算机图形学原理算法教程(visual.cpp版)》目录如下: 第一部分:基础知识 1. 引言 2. 计算机图形学概述 3. 图形学的数学基础 4. 图形处理与显示设备 第二部分:二维图形学 5. 坐标系与坐标变换 6. 线段的生成与显示 7. 多边形的生成与显示 8. 填充算法 9. 图形的变换与合成 第三部分:三维图形学 10. 三维坐标系与坐标变换 11. 三维线段的生成与显示 12. 多边形的三维表示与显示 13. 曲线与曲面的显示与生成 14. 光照模型与着色算法 第四部分:三维图形学算法进阶 15. 线框图与隐藏线消除 16. 精确三维图形的表示与显示 17. 投影算法与视图变换 18. 光线追踪与阴影效果 19. 纹理映射与纹理合成 第五部分:图形学应用与案例分析 20. 计算机游戏中的图形学应用 21. 虚拟现实与增强现实中的图形学应用 22. 图形学在电影制作中的应用 23. 图形学在工业设计与建筑设计中的应用 24. 图形学在医学图像处理中的应用 第六部分:附录 25. 常用图形学算法与数据结构概述 26. 编程实践与实例示范 27. 常见图形学库与软件介绍 28. 参考文献 《计算机图形学原理算法教程(visual.cpp版)》第二版的目录包含了基础知识、二维图形学、三维图形学、三维图形学算法进阶、图形学应用与案例分析以及附录等六个部分。通过阅读该书籍,读者可以系统地学习计算机图形学原理算法,并且了解图形学的应用领域和实践指导。附录部分提供了常见图形学算法与数据结构概述、编程实践与实例示范、常见图形学库与软件介绍以及参考文献等有用的补充信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值