(6)圆的生成之中点画圆法

圆的特性 

圆被定义为所有离一中心位置(xc, yc)距离为给定值r的点集,可用方程表示为:
                (x – xc)*(x – xc) +(y – yc)*(y – yc) = r*r

圆的对称性

已知一个圆心在原点的圆上一点为(x, y),根据对称性,可得另外七个8分圆上的对应点(y, x),(y, –x),(x, –y),(–x, –y),(–y, –x),(–y, x),(–x, y)。


中点画圆法

基本原理:
根据圆的对称性,只需讨论1/8圆弧(取第一象限内以y=x为界的上半部分),即确定最佳逼近于该圆弧的像素点集。

假定当前已确定了圆弧上的一个像素点为P(xp,yp),则下一个像素只能是正右方的P1(xp+1, yp)或右下方的P2(xp+1, yp–1)。

构造函数:F (x, y) = x*x+y*y – r*r
1)对于圆上的点,F (x, y) = 0;
2)对于圆外的点,F (x, y) > 0;
3)对于圆内的点,F (x, y) < 0。

设M是P1和P2的中点,即M = (xp+1, yp–0.5)
1)若F (M)>0,则M在圆外,P2离圆弧更近,取P2为下一像素
2)若F (M)<0,则M在圆内,P1离圆弧更近,取P1为下一像素
3)若F (M)=0,在P1和P2中任取一个即可,约定取P2

构造判别式:
                    d = F(M)= F (xp+1, yp–0.5)   
                      =(xp+1)*(xp+1) + (yp–0.5)*(yp–0.5) – r*r         (1式)
若d<0,取P1为下一像素,则再下一个像素的判别式为:
                     d1 = F (xp+2, yp–0.5)
                       = (xp+2)*(xp+2) + (yp–0.5)*(xp+2) – r*r     
                       = d + 2xp + 3
所以沿正右方向,d 的增量为2xp+3 

若d≥0,取P2为下一像素,则再下一个像素的判别式为:
                    d2 = F(xp+2, yp–1.5)
                      = (xp+2)*(xp+2) + (yp–1.5)*(yp–1.5) – r*r
                      = d + (2xp +3)+(–2yp +2)
所以沿右下方向,d 的增量为2(xp–yp)+ 5 

d的初始值:从圆的正上方开始,第一个像素是(0, r),代入到1式,则判别式 d 的初始值为:
               d0 = F (1, r – 0.5)= 1+(r – 0.5)*(r – 0.5) – r*r = 1.25 – r 


中点画圆法的算法步骤:
1. 输入圆的半径r。
2. 计算初始值d=1.25-r,x=0,y=r,画点(x, y)。
3. 若x<y,则执行下列各步,否则算法结束。
4. 求下一个点:若d<0,则先将d更新为d+2x+3,再将(x, y)更新为(x+1, y);否则先将d更新为d+2(x-y)+5,再将(x, y)更新为(x+1, y-1)。
5. 画点(x, y),返回3。


中点画圆法的改进:
1)若用e = d – 0.25代替d,则d0 = 1.25 – r 对应于e0 = 1 – r。
2)判别式d<0对应于e < –0.25。算法中其他与d有关的式子可把d直接换成e。这样,就可以写出完全用整数实现的中点画圆算法。


改进后的中点画圆法的算法步骤:
1. 输入圆的半径r。
2. 计算初始值d=1-r,x=0,y=r,画点(x, y)。
3. 若x<y,则执行下列各步,否则算法结束。
4. 求下一个点:若d<0,则先将d更新为d+2x+3,再将(x, y)更新为(x+1, y);否则先将d更新为d+2(x-y)+5,再将(x, y)更新为(x+1, y-1)。
5. 画点(x, y),返回3。


代码:

void wholeC(int xc, int yc, int x, int y, int color) {
	putpixel(xc + x, yc + y, color); putpixel(xc + x, yc - y, color);
	putpixel(xc - x, yc + y, color); putpixel(xc - x, yc - y, color);
	putpixel(xc + y, yc + x, color); putpixel(xc + y, yc - x, color);
	putpixel(xc - y, yc + x, color); putpixel(xc - y, yc - x, color);
}
void Mcircle(int xc, int yc, int r, int color) {
	int x = 0, y = r, d = 1 - r;
	wholeC(xc, yc, x, y, color);
	while (x <= y) {
		if (d < 0) {
			d += 2 * x + 3;
			x++;
		}
		else {
			d += 2 * (x - y) + 5;
			x++;
			y--;
		}
		wholeC(xc, yc, x, y, color);
	}
}

    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值