OpenGL——使用Bresenham算法绘制圆
Bresenham算法是计算机图形学中为了“显示器(屏幕或打印机)系由像素构成”的这个特性而设计出来的算法,使得在求直线各点的过程中全部以整数来运算,因而大幅度提升计算速度。——摘自 “百度百科”。
Bresenham算法绘制直线就不赘述了,大家看一看算法简介就能很好理解与实践。
稍稍麻烦一点的就是用该算法绘制圆了,算法思想其实是一样的,并没有太大改变。
算法核心:
组合以上式子,当Dupper-Dlower<0时,取上点;当Dupper-Dlower>0时,取下点;否则任意。
实验过程中,我使用了两种方法:① 画点法 ② 连线法。
一、 画点法:
画点法就是仅仅用OpenGL绘制点。可以选择按照圆的轨迹画整个圆,当然这样的算法要比较慢,而且要注意分段函数的增减性。
我使用的是对称法,利用圆的对称性质,仅仅计算1/8的圆弧的点(当然算1/4也可以),其余的点均用对称性直接绘制。如下图所示:
代码如下:
1 /* 2 * Draw Circle by Bresenham Algorithm 3 * @para < xc, yc - 圆心: (xc, yc) > 4 * @para < r - 半径 > 5 * @para < deltaX - 坐标系每个小格的间距,用于控制精细度 > 6 */ 7 void drawCircle_Bresenham(GLfloat xc, GLfloat yc, GLfloat r, const GLfloat deltaX) { 8 GLfloat xi = - r, yi = 0; /* 圆上点 (xi, yi) */ 9 GLfloat du_l; /* upper - lower */ 10 glBegin(GL_POINTS); 11 while (abs(xi) >= abs(yi)) { 12 // 根据圆的八向对称,只计算其中八分之一的点,然后对称得出其他点 13 // 假设圆心在原点,先求点,再平移 14 glVertex2f(xc + xi, yc + yi); 15 glVertex2f(xc - xi, yc + yi); 16 glVertex2f(xc + xi, yc - yi); 17 glVertex2f(xc - xi, yc - yi); 18 glVertex2f(xc + yi, yc + xi); 19 glVertex2f(xc - yi, yc + xi); 20 glVertex2f(xc + yi, yc - xi); 21 glVertex2f(xc - yi, yc - xi); 22 23 xi += deltaX; // 下一个x 24 float yi_1 = sqrt(pow((GLfloat)r, 2) - pow((GLfloat)xi, 2)); // yi+1 25 du_l = 2 * (GLfloat)yi + deltaX - 2 * yi_1; 26 yi = (du_l <= 0) ? (int)yi_1 + deltaX : (int)yi_1; 27 } 28 glEnd(); 29 glFlush(); 30 }
结果如图(半径150,圆心在原点,横坐标间隔为0.001):
二、 画线法:
根据圆弧四个象限的增减性和凹凸性的不同,分别绘制四段曲线,组合成一个圆。核心算法和第一种方法相同。
1 const GLint FIRST_QUA = 1; // 第一象限 2 const GLint SECOND_QUA = 2; // 第二象限 3 const GLint THIRD_QUA = 3; 4 const GLint FOURTH_QUA = 4; 5 6 /* 7 * 根据起点和终点绘制弧(画线法) 8 * @para < deltaX - 坐标系每个小格的间距,用于控制精细度 > 9 * @para < Quadrant - 象限 > 10 */ 11 void setPixel(GLfloat startX, GLfloat endX, GLfloat startY, GLfloat xc, GLfloat yc, GLfloat r, GLfloat deltaX, GLint Quadrant) { 12 GLfloat du_l; /* upper - lower */ 13 int inc = (Quadrant % 2 == 1) ? -1 : 1; 14 int nag = (Quadrant > 2) ? -1 : 1; 15 glBegin(GL_LINE_STRIP); 16 while (startX <= endX) { 17 // 假设圆心在原点,先求点,再平移 18 glVertex2f(startX + xc, startY + yc); 19 startX += deltaX; 20 float yi_1 = nag * sqrt(pow((GLfloat)r, 2) - pow((GLfloat)startX, 2)); // yi+1 21 du_l = 2 * (GLfloat)startY + inc * deltaX - 2 * yi_1; 22 startY = (du_l <= 0) ? (int)yi_1 + deltaX : (int)yi_1; 23 } 24 glEnd(); 25 } 26 27 /* 28 * Bresenham 算法(画线法) 29 * @para < xc, yc - 圆心(xc, yc) > 30 * @para < r - 半径 > 31 */ 32 void drawCircle_Bresenham_line(GLfloat xc, GLfloat yc, GLfloat r, GLfloat deltaX) { 33 setPixel(-r, 0, 0, xc, yc, r, deltaX, SECOND_QUA); // 左上半 34 setPixel(0, r, r, xc, yc, r, deltaX, FIRST_QUA); // 右上半 35 setPixel(0, r , -r, xc, yc, r, deltaX, FOURTH_QUA); // 右下半 36 setPixel(-r, 0, 0, xc, yc, r, deltaX, THIRD_QUA); // 左下半 37 glFlush(); 38 }
结果如图(半径150,圆心在原点,横坐标间隔为0.001):
转载于:https://www.cnblogs.com/xulf/p/4357875.html
OpenGL——使用Bresenham算法绘制圆相关推荐
- bresenham算法_二维光栅图形的扫描:直线的DDA、Bresenham算法与圆的生成
数值微分DDA算法 算法原理 DDA算法是一个增量算法,每一步的x.y值是用前一步的值加上一个增量来获得的,每一步在最大位移方向上加1. 优点:算法直观.易实现 缺点:有浮点数和浮点运算,效率不高 代 ...
- 基于中点算法和Bresenham算法绘制椭圆
方法一 一.设计思路 该实验利用中点算法和Bresenham算法寻找最逼近椭圆的理想像素集. 对于,判断下一点取还是, 先取中点,判断该中点在圆内还是圆外, 若在圆外,说明椭圆上的点离下方的像素点更 ...
- Wu反走样算法绘制圆(C++/MFC实现)
Wu反走样圆 原理:参考Bresenham算法,在主位移过程中计算出离理想圆最近的两个点,赋予不同的亮度值,绘制像素点即可! MFC 中CXXXView类中添加函数: //Wu算法画反走样圆 void ...
- Bresenham算法画圆
中点画圆法中,计算判别式d使用了浮点运算,影响了圆的生成效率.如果能将判别式规约到整数运算,则可以简化计算,提高效率.于是人们针对中点画圆法进行了多种改进,其中一种方式是将d的初始值由1.25 – R ...
- bresenham算法画圆mfc实现_kd-tree理论以及在PCL 中的代码的实现
通过雷达,激光扫描,立体摄像机等三维测量设备获取的点云数据,具有数据量大,分布不均匀等特点,作为三维领域中一个重要的数据来源,点云主要是表征目标表面的海量点的集合,并不具备传统网格数据的几何拓扑信息, ...
- bresenham算法画圆c语言,bresenham画圆算法
中点画圆算法在一个方向上取单位间隔,在另一个方向的取值由两种可能取值的中点离圆的远近而定.实际处理中,用决策变量的符号来确定象素点的选择,因此算法效率较高. 设要显示圆的圆心在原点(0,0),半径为R ...
- OpenGL实现Hermite算法绘制三次曲线
首先是推导:节省功夫我就直接贴照片了. 程序加了鼠标的监听器,可以移动控制点和型值点. 注意:图片中矩阵第二行第二列应该为3,当时笔误 程序效果: 代码如下: #include<gl/glut. ...
- 计算机图形学上机报告绘制圆,计算机图形学上机实验报告
实验一:基本图形的绘制 一.实验目的与要求 (1)理解glut程序框架: (2)理解窗口到视区的变换 ; (3)理解OpenGL实现动画的原理: (4)添加代码实现中点Bresenham算法画直线: ...
- 布兰森汉姆画圆matlab,bresenham算法画直线
实验一名称:基本图形的生成算法 要求:(1)掌握 DDA 生成线段算法 (2)掌握 Bresenham 生成线段算法 (3)掌握生成圆弧算法 1. 代码 (1) Bresenham 画线算法 v 实验 ...
最新文章
- Java基础篇(04):日期与时间API用法详解
- springboot项目根据不同的环境启动不同的配置,如开发环境dev,测试环境sit,生产环境application...
- js根据数组中对象的多个属性值进行排序
- java http 返回值_java发送http请求,无需等待返回结果
- iframe页面找父页面的元素
- 程序员降薪求职到底该不该?
- English trip M1 - AC9 Nosey people 爱管闲事的人 Teacher:Solo
- 用Python筛选国考职位表
- map转list对象方法,通过stream或者iterator.key集合转list,values集合转list
- linux bridge 添加fdb,Linux协议栈--网桥设备的实现
- 学习笔记之Python的六种内置对象
- gtp怎么安装系统_UEFI+GTP模式下使用GHO文件安装Win8系统的具体操作方法
- (01)ORB-SLAM2源码无死角解析-(37) EPnP 算法原理详解→理论基础一:控制点选取、透视投影约束
- 清华大学计算机科学与技术系朱军教授:机器学习里的贝叶斯基本理论、模型和算法
- 某计算机系统20位地址线 8位数据线,同济大学2009-2010(1)微机原理期终试题(A B卷)含答案.doc...
- unity Font字体替换
- CSS3字体样式及高级特效
- Win10 + Ubuntu双系统U盘安装,详细过程(带图解)
- 使用imagine/imagine实现制作一个图片
- 小程序textarea在ios中内边距的解决办法
热门文章
- This is very likely to create a memory leak.
- linux kill进程
- qt linux 鼠标事件,QT学习笔记5:QMouseEvent鼠标事件简介
- comsol固体传热_【 COMSOL 知识库】如何解决 COMSOL 软件“内存不足” 的问题
- android oom 检测工具,Android中UI检测、内存泄露、OOM、等优化处理
- python diff函数_使用Python创建你自己的diff工具
- java logger 静态,java11教程--公共静态接口System.Logger
- c#推箱子小游戏代码_推箱子小游戏V1.0制作
- java 传递函数_java传递函数参数(值传递)
- vs 创建控制器 一直收集信息_日产Pro-Pilot的ADAS控制器拆解