计算机图形学——圆的扫描转换(基本光栅图形算法)
与直线的生成类似,圆弧生成算法的好坏直接影响到绘图的效率。本篇博客将讨论圆弧生成的3个主要算法,正负法、Bresenham法和圆的多边形迫近法,在介绍算法时,只考虑圆心在原点,半径为R的情况。
一、正负法
1、基本原理
假设已选取Pi-1为第i-1个像素,则如果Pi-1在圆内,就要向圆外方向走一步;若已在圆外就要向圆内走一步。
总之,尽量贴近圆的轮廓线。
2、正负法的具体实现
1)圆的表示:设圆的圆心为(0,0),半径为R,则圆的方程为:
F(x,y)=x2+y2–R2=0
当点(x,y)在圆内时,F(x,y)<0。
当点(x,y)在圆外时,F(x,y)>0。
2)实现步骤
第1步:x0=0,y0=R
第2步:
求得Pi(xi,yi)后找点Pi+1的原则为:
当Pi在圆内时(F(xi,yi)≤0),要向右走一步得Pi+1,这是向圆外方向走去。取xi+1= xi+1, yi+1= yi
当Pi在圆外时(F(xi,yi)>0),要向下走一步得Pi+1,这是向圆内方向走去,取xi+1= xi, yi+1= yi-1
用来表示圆弧的点均在圆弧附近且 F(xi, yi)时正时负
假设已经得到点(xi, yi),则容易算出F(xi, yi),即确定了下一个点(xi+1, yi+1),则如何计算F(xi+1, yi+1),以确定下下个点(xi+2, yi+2)?
分为两种情况:
右走一步后:xi+1=xi+1,yi+1=yi,此时:
F(xi+1, yi+1)=xi+12+yi2-R2 =xi2+yi2-R2+2xi+1 = F(xi, yi)+2xi+1
下走一步后:xi+1=xi,yi+1=yi-1, 此时:
F(xi+1, yi+1)=xi2+(yi-1)2-R2 = F(xi, yi)-2yi+1
由此可得:
确定了F(xi+1, yi+1)之后,即可决定下一个点(xi+2, yi+2),选择道理同上。
二、Bresenham 生成圆弧的算法
Bresenham算法是最常用的画圆的算法之一假设圆心(0,0)为原点,考虑AB弧的画法,显示一个整圆时,只要在显示AB上任一点(x,y)时,同时显示在圆周上其它七个对称点(y,x), (y,-x), (x,-y), (-x,-y),(-y,-x), (-y,x), (-x,y)。
1、基本原理
考虑AB弧段,x每步增加1,从 x=0开始,到x=y结束。
即有:
xi+1=xi+1 相应的yi+1则在两种可能中选择 yi+1=yi (Hi点)或者 yi+1=yi-1(Li点)
所以:
选择的原则是确定这两个点哪一个更接近于圆弧。
即:设Pi-1是已选中的一个表示圆弧上的点,下一个点应从Hi或Li中选择。设Hi和Li两点的坐标分别为(xhi, yhi)和(xli, yli)
设R为弧AB的半径,记点P到原点的距离的平方与圆的半径的平方之差为D(P),即
2、递推公式
di决定的是(xi, yi),即Hi和Li哪个被选中
di+1则决定的是(xi+1, yi+1),即Hi+1和Li+1哪个被选中
当di<0时,点Hi被选中, xi= xi-1+1, yi=yi-1,由 (3.13)和(3.14)得
di+1= di+ 4xi+2= di+ 4xi-1+6
当di≥0时,点Li被选中, xi= xi-1+1,yi= yi-1-1,由(3.13)和(3.14)得
di+1=di+4xi-4yi-1+6=di+4(xi-1-yi-1)+10
3、代码实现
根据上面得到的递推表达式,可以获得该算法生成弧AB的代码如下:
void bresenham_arc(Graphics g,int radius) { int x,y,d; x = 0; y = radius; d = 3-2*radius;//d1 while (x < y) { g.drawLine(x, y, x, y); if (d<0) d=d+4*x+6; else { d=d+4*(x-y)+10; y--; } x++; } if (x == y) g.drawLine(x,y,x,y); }
Bresenham算法在候选的两个像素中,总是选定离圆弧最近的像素为圆弧的一个近似点,因此,Bresenham算法比正负法决定的像素更合理。
三、圆的多边形迫近法
1、基本思想
将整个圆弧等分成一段段的短直线,用这些短直线形成的折线来逼近圆弧。为了获得这些短直线,只需按一定的方式计算给定圆弧轨迹上一系列顶点,短直线的绘制可采用直线的生成算法,如果将圆弧分割的足够密,则短直线将足够短,形成的折线将可以和圆弧接近到任意程度,因此在允许的误差范围内,可以用显示折线代替显示圆弧。
2、圆弧的离散生成
设圆的圆心为c(0,0),半径为R。假设圆弧的起始角和终止角分别为α0和α1,把圆弧分割为n份,则两个顶点之间的夹角为 α=( α1 - α0 )/n 。
设内接正多边形的一个顶点为Pi(xi,yi),cPi的幅角为θi,则
xi=Rcosθi
yi=Rsinθi
顶点Pi+1的坐标为
xi+1=Rcos(θi+α)= xicosα-yisinα
yi+1=Rsin(θi+α)= xisinα+yicosα
或表示为矩阵形式:
计算一个点(xi+1,yi+1)只要作四次乘法。
由此决定了一系列顶点,两个定点确定一条直线,n条直线逼近了个整个圆。