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

计算机是如何画直线的?简单来说,如下图所示,真实的直线是连续的,但我们的计算机显示的精度有限,不可能真正显示连续的直线,于是我们用一系列离散化后的点(像素)来近似表现这条直线。

(上图来自于互联网络,《计算机图形学的概念与方法》柳朝阳,郑州大学数学系)

接下来的问题就是如何尽可能高效地找到这些离散的点,

Bresenham直线算法是用来描绘由两点所决定的直线的算法,它会算出一条线段在 n 维光栅上最接近的点。这个算法只会用到较为快速的整数加法、减法和位元移位,常用于绘制电脑画面中的直线。是计算机图形学中最先发展出来的算法。

(引自wiki百科布雷森漢姆直線演算法)

这个算法的流程图如下:

可以看到,算法其实只考虑了斜率在 0 ~ 1 之间的直线,也就是与 x 轴夹角在 0 度到 45 度的直线。只要解决了这类直线的画法,其它角度的直线的绘制全部可以通过简单的坐标变换来实现。

下面是一个C语言实现版本。

// 交换整数 a 、b 的值

inline void swap_int(int *a, int *b) {

*a ^= *b;

*b ^= *a;

*a ^= *b;

}

// Bresenham's line algorithm

void draw_line(IMAGE *img, int x1, int y1, int x2, int y2, unsigned long c) {

// 参数 c 为颜色值

int dx = abs(x2 - x1),

dy = abs(y2 - y1),

yy = ;

if (dx < dy) {

yy = ;

swap_int(&x1, &y1);

swap_int(&x2, &y2);

swap_int(&dx, &dy);

}

int ix = (x2 - x1) > ? : -,

iy = (y2 - y1) > ? : -,

cx = x1,

cy = y1,

n2dy = dy * ,

n2dydx = (dy - dx) * ,

d = dy * - dx;

if (yy) { // 如果直线与 x 轴的夹角大于 45 度

while (cx != x2) {

if (d < ) {

d += n2dy;

} else {

cy += iy;

d += n2dydx;

}

putpixel(img, cy, cx, c);

cx += ix;

}

} else { // 如果直线与 x 轴的夹角小于 45 度

while (cx != x2) {

if (d < ) {

d += n2dy;

} else {

cy += iy;

d += n2dydx;

}

putpixel(img, cx, cy, c);

cx += ix;

}

}

}

可以看到,在画线的循环中,这个算法只用到了整数的加法,所以可以非常的高效。

接下来,我们再来看一看Bresenham画圆算法。

Bresenham画圆算法又称中点画圆算法,与Bresenham 直线算法一样,其基本的方法是利用判别变量来判断选择最近的像素点,判别变量的数值仅仅用一些加、减和移位运算就可以计算出来。为了简便起见,考虑一个圆 心在坐标原点的圆,而且只计算八分圆周上的点,其余圆周上的点利用对称性就可得到。

为什么只计算八分圆周上的点就可以了呢?和上面的直线算法类似,圆也有一个“八对称性”,如下图所示。

显然,我们只需要知道了圆上的一个点的坐标 (x, y) ,利用八对称性,我们马上就能得到另外七个对称点的坐标。

和直线算法类似,Bresenham画圆算法也是用一系列离散的点来近似描述一个圆,如下图。

(上图来自于互联网络,《计算机图形学的概念与方法》柳朝阳,郑州大学数学系)

Bresenham画圆算法的流程图如下。

可以看到,与画线算法相比,画圆的循环中用到了整数的乘法,相对复杂了一些。

下面是一个C语言实现版本。

// 八对称性

inline void _draw_circle_8(IMAGE *img, int xc, int yc, int x, int y, unsigned long c) {

// 参数 c 为颜色值

putpixel(img, xc + x, yc + y, c);

putpixel(img, xc - x, yc + y, c);

putpixel(img, xc + x, yc - y, c);

putpixel(img, xc - x, yc - y, c);

putpixel(img, xc + y, yc + x, c);

putpixel(img, xc - y, yc + x, c);

putpixel(img, xc + y, yc - x, c);

putpixel(img, xc - y, yc - x, c);

}

//Bresenham's circle algorithm

void draw_circle(IMAGE *img, int xc, int yc, int r, int fill, unsigned long c) {

// (xc, yc) 为圆心,r 为半径

// fill 为是否填充

// c 为颜色值

// 如果圆在图片可见区域外,直接退出

if (xc + r < || xc - r >= img->w ||

yc + r < || yc - r >= img->h) return;

int x = , y = r, yi, d;

d = - * r;

if (fill) {

// 如果填充(画实心圆)

while (x <= y) {

for (yi = x; yi <= y; yi ++)

_draw_circle_8(img, xc, yc, x, yi, c);

if (d < ) {

d = d + * x + ;

} else {

d = d + * (x - y) + ;

y --;

}

x++;

}

} else {

// 如果不填充(画空心圆)

while (x <= y) {

_draw_circle_8(img, xc, yc, x, y, c);

if (d < ) {

d = d + * x + ;

} else {

d = d + * (x - y) + ;

y --;

}

x ++;

}

}

}

可以看到,Bresenham画圆算法(中点圆算法)的实现也非常简单。在另一个项目中,我还有一个 Python 实现的版本,不过那段代码和其余部分结合得比较紧,有点难抠,这次就不贴出来了。

中点Brehensam画圆算法

#include #include #include #include v ...

基于Bresenham算法画圆

bresenham算法画圆思想与上篇 bresenham算法画线段 思想是一致的 画圆x^2+y^2=R^2 将他分为8个部分,如上图 1. 只要画出1中1/8圆的圆周,剩下的就可以通过对称关系画出这 ...

中点Bresenham画圆

这里不仔细讲原理,只是把我写的算法发出来,跟大家分享下,如果有错误的话,还请大家告诉我,如果写的不好,也请指出来,一起讨论进步. 算法步骤: (1) 输入圆的半径R. (2) 计算初始值d = 1 - ...

《图形学》实验六:中点Bresenham算法画圆

开发环境: VC++6.0,OpenGL 实验内容: 使用中点Bresenham算法画圆. 实验结果: 代码: #include #define WIDTH 500 ...

&lbrack;计算机图形学&rsqb; 基于C&num;窗口的Bresenham直线扫描算法、种子填充法、扫描线填充法模拟软件设计(二)

上一节链接:http://www.cnblogs.com/zjutlitao/p/4116783.html 前言: 在上一节中我们已经大致介绍了该软件的是什么.可以干什么以及界面的大致样子.此外还详细 ...

【转】【OPenGL】OPenGL 画图板-- 中点算法画圆

为了能以任意点为圆心画圆,我们可以把圆心先设为视点(相当于于将其平移到坐标原点),然后通过中点法扫描转换后,再恢复原来的视点(相当于将圆心平移回原来的位置). 圆心位于原点的圆有四条对称轴x=0,y= ...

Bresenham画线算法

[Bresenham画线算法] Bresenham是一种光栅化算法.不仅可以用于画线,也可以用用画圆及其它曲线. 通过lower与upper的差,可以知道哪一个点更接近线段: 参考:

WebGIS中基于AGS的画圆查询简析以及通过Polygon来构造圆的算法

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.背景 某个项目需求中需要在前端进行画圆查询,将圆范围上的多边形要素 ...

两种画线算法&lpar;DDA&amp&semi;Bersenham&rpar;

DDA(digital differential analyzer) 由直线的斜截式方程引入 对于正斜率的线段,如果斜率<=1,则以单位x间隔(δx=1)取样,并逐个计算每一个y值 Yk+1 = ...

随机推荐

CSS3学习总结——实现瀑布流布局与无限加载图片相册

首先给大家看一下瀑布流布局与无限加载图片相册效果图: 一.pic1.html页面代码如下:

&lbrack;Android&rsqb;Android端ORM框架——RapidORM&lpar;v2&period;1&rpar;

以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/6020412.html [Android]Android端ORM ...

nginx负载均衡最新

配置conf文件 #user  nobody;worker_processes  1;#error_log  logs/error.log;#error_log  logs/error.log  no ...

&lbrack;VSTS&rsqb; 从零开始 Team Foundation Server 2010 安装配置详细图文教程

http://www.cnblogs.com/WilsonWu/archive/2011/11/24/2261674.html 近期公司要配TFS用于新项目的管理,公司也将逐步迁移至VSTS平台,前期 ...

30天,O2O速成攻略【7&period;25北京站】

活动概况 时间:2015年7月25日13:30-16:30 地点:车库咖啡(北京市海淀西大街48号鑫鼎宾馆二层) 主办:APICloud.领通科技.快易行 网址:www.apicloud.com 费用 ...

Oracle 过程控制语句整理

分支语句/循环语句 v_case ) :; begin then dbms_output.put_line('条件成立'); elsif then then dbms_output.put_line( ...

oc-25- &commat;property &commat;synthesize

s.h #import @interface Student : NSObject { @public NSString *_name; ...

css布局之选择切换按钮

python3画圆、直线_Bresenham直线算法与画圆算法相关推荐

  1. 图形学基础笔记I:直线和圆的光栅算法、中点线算法、中点圆算法

    实际现代显卡支持的图元就只有点.线.三角形.这是基于这样的事实: 实际对于 3D 来说肯定全是基于三角形的 geometry - OpenGL: Is it more efficient to use ...

  2. (重点)C#/Csharp桌面应用开发小作业小程序,测距仪,画圆,GDI画圆,画直线,绘制圆,绘制直线,绘制虚线,dashpattern的应用

    简介 这次试验具有一定难度,因为我们对于C#得画板接触得比较少,但是我认为老师很可能在考试的时候在这上面大出文章,所以这个实验我会详细的解析C#的GDI+ 首先,我们要画图形,就要调用Paint方法, ...

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

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

  4. Python实现的直线段生成算法和圆弧生成算法

    资源下载地址:https://download.csdn.net/download/sheziqiong/86768948 资源下载地址:https://download.csdn.net/downl ...

  5. opencv霍夫变换检测圆cvHoughCircles和直线cvHoughLines2的应用

    opencv霍夫变换检测圆cvHoughCircles和直线cvHoughLines2的应用 1)cvHonghLines2:直线 2)cvHoughCircles:该函数用Hough变换在二值图像中 ...

  6. cad角度怎么画_软件CAD | 直线amp;构造线

    点击这里查看上一期推送哦~ 半平米工坊:软件CAD | 各种"线"工具​zhuanlan.zhihu.com 大家好,在前两次的推送中,我们将CAD的界面.操作逻辑都过了一遍,学过 ...

  7. 关于google地图api3的离线和在线开发(画带箭头的直线,指定范围,搜索,计算距离)

    最近因为开发的需要,要做一个离线的google地图.并且能够加载google地图的一些特效.例如:地图的标记,计算距离,获取标记的经纬度,画带有箭头的直线,获取指定范围的数据等等.在这里我总结了很多开 ...

  8. 直线与直线、直线与圆、直线与矩形的交点

    求直线与直线.直线与圆.直线与矩形的交点 直线与直线的交点:a1x + b1x + c1x = 0 与 a2x + b2x + c2x = 0的交点坐标可直接根据公式x = (b1c2 - b2c1) ...

  9. 直线和直线,直线和圆,直线和矩形的交点

    直线和圆的交点公式 y=kx+b (x+c)² + (y+d)² = r² 的形式 转换成 ax+by+c=0 以(x, y)为圆心,r 为半径的形式 c++ // ax+by+c=0 // (x, ...

最新文章

  1. jdk 环境配量配置
  2. 算法应用 ---拆分字符串为n节字符
  3. Spring与Oauth2整合示例 spring-oauth-server
  4. 织梦html底部文件,织梦dedecms程序如何给网站底部添加360监控的步骤
  5. Ubuntu 14.04 Ruby 2.3.3 安装
  6. 【优化调度】基于matlab遗传算法求解码头泊位分配调度优化问题【含Matlab源码 247期】
  7. 洛谷OJ P3865 【模板】ST表
  8. 内链接和外连接的区别
  9. 小米浏览器导出html,小米浏览器离线视频如何导出 小米浏览器离线视频导出教程...
  10. 计算机多媒体技术所处理的六个,多媒体技术
  11. 程序员打造影响力常犯的 3 个错
  12. 伸展树(二) - C++实现
  13. WAP流量变现的几种方式
  14. 互联网+双“高新”时代
  15. 11月24日学习笔记_map/reduct的应用于使用
  16. 微信小程序的废品回收类程序 垃圾回收app#毕业设计
  17. Emacs: Failed to verify signature archive-contents.sig或gpg: 无法检查签名:没有公钥
  18. 热式气体质量流量计检定规程_最佳实践:热式质量流量计实际标定的安全性和准确性...
  19. 小程序毕设作品之微信美食菜谱小程序毕业设计成品(3)后台功能
  20. FZU1901 Period II

热门文章

  1. 微软产的避孕套最好?
  2. 环材化生劝退文章汇总
  3. 应用出海活跃,开发教程
  4. 台式计算机如何设置屏幕亮度,台式电脑屏幕怎么调亮度
  5. ZT 乔.吉拉德销售秘诀
  6. 通过106短信群发的方式进行营销推广对教育行业意味着什么
  7. spotify使用教程_什么是Spotify Kids? (以及如何使用其家长控制)
  8. 美团一、二、三面面经(java后台开发,小象事业部)
  9. PhotoshopCC2014安装Adobe Color CC Panel
  10. mac pro java后端开发环境搭建