直线算法与画圆算法_第1页
直线算法与画圆算法_第2页
直线算法与画圆算法_第3页
直线算法与画圆算法_第4页
直线算法与画圆算法_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

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

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

接下来的问题就是如何尽可能高效地找到这些离散的点,Bresenham直线算法就是一个非常不错的算法。

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

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

这个算法的流程图如下:

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

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

view

sourceprint?

//

交换整数

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

=

0;

if(dx

<

dy)

{

yy

=

1;

swap_int(&x1,

&y1);

swap_int(&x2,

&y2);

swap_int(&dx,

&dy);

}

int

ix

=

(x2

-

x1)

>

0

?

1

:

-1,

iy

=

(y2

-

y1)

>

0

?

1

:

-1,

cx

=

x1,

cy

=

y1,

n2dy

=

dy

*

2,

n2dydx

=

(dy

-

dx)

*

2,

d

=

dy

*

2

-

dx;

//

如果直线与

x

轴的夹角大于45度

if(yy)

{

while(cx

!=

x2)

{

if(d

<

0)

{

d

+=

n2dy;

}

else

{

cy

+=

iy;

d

+=

n2dydx;

}

putpixel(img,

cy,

cx,

c);

cx

+=

ix;

}

}

//

如果直线与

x

轴的夹角小于

else

{

while(cx

!=

x2)

{

if(d

<

0)

{

d

+=

n2dy;

}

else

{

cy

+=

iy;

d

+=

n2dydx;

}

putpixel(img,

cx,

cy,

c);

cx

+=

ix;

}

}

}

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

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

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

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

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

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

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

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

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

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

view

sourceprint?

//

八对称性

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

<

0

||

xc

-

r

>=

img->w

||

yc

+

r

<

0

||

yc

-

r

>=

img->h)

{

return;

}

int

x

=

0,

y

=

r,

yi,

d;

d

=

3

-

2

*

r;

if(fill)

{

//

如果填充(画实心圆)

while(x

<=

y)

{

for(yi

=

x;

yi

<=

y;

yi

++)

{

_draw_circle_8(img,

xc,

yc,

x,

yi,

c);

}

if(d

<

0)

{

d

=

d

+

4

*

x

+

6;

}

else

{

d

=

d

+

4

*

(x

-

y)

+

;

y

--;

}

x++;

}

}

else

{

//

如果不填充(画空心圆)

while

(x

<=

y)

{

_draw_circle_8(img,

xc,

yc,

x,

y,

c);

if(d

<

0)

{

d

=

d

+

4

*

x

+

6;

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论