中点圆算法

来自我的Page

1.圆的两个简单生成算法

(xxc)2+(yyc)2=r2

其中 (xc,yc)为圆心坐标,变换上述方程,得到:
y=yc±r2(xcx)2

于是我们可以通过扫描 (xcr,xc+r)区间上对应的点在屏幕上绘出圆来。但是这种方法虽然简单,但是效率低下。
另一种方法是考虑极坐标来表示圆的方程,方程组:
{x=xc+rcosθ y=yc+rsinθ

实现代码:


void setRound(GLint xc,GLint yc,GLint N,GLfoat *color){
for (int i = 0; i <N; ++i)
{
setPixelf(100+R*cos(2*Pi/N*i),100+R*sin(2*Pi/N*i),color);
}
}
上述代码确实可行,但是引入三角函数来计算有点耗时。

2.中点圆算法

中点圆算法是光栅扫描转换里面基本的算法,也叫Bresenham画圆算法。我们在实际生成圆时,由于圆的对称性,将圆划分成八个部分,即八分圆,只要计算一个八分圆,我们就可以映射到其余七个八分圆(先将圆心设为坐标轴原点,最后再作平移)。
如图:

我们现在只考虑从x=0x=y的圆弧段,圆上任一点P_i(xi,yi),那么下一个像素的选择就在集合{E,SE}中选择。对于ESE的中点M点,构造一个M点和圆的方程的位置函数:

fM(x,y)=x2+y2r2.

fM(x,y)有三种可能的情况,
fM(x,y)=>0,M(SE) =0M(SE) <0,M(E) 

M(xi+1,yi12)代入 fM(x,y)方程中,有
dold=(xi+1)2+(yi12)2r2.

dold<0,则选 E点,下一个中点 M对应的 fM(x,y)值为
dnew=(xi+2)2+(yi122)r2

ΔE=dnewdold=2xi+3.
同理, dold>0,SEMfM(x,y)
dnew=(xi+2)2+(yi32)2r2

ΔE=dnewdold=2xi2yi+5.
由于圆的起始位置为 (0,r),第一个中点坐标为 (1,r12),
d=fM(1,r12)=1+(r2r+14)r2=54r.注意到在实际计算时 x,y的增量都为整数,我们可以令初始值 d=1r,这并不会改变 d的符号。

中点圆算法生成算法代码

void MidpointCircle(GLint radius,GLint xc,GLint yc,GLfloat *color)
{
GLint x,y,d;
x=0,y=radius,d=1-radius;
setPixeli(xc,yc+y,color);
while(y>x)
{
if(d<0)//此时在第二个八分圆处,中点在圆内,选上方的点
{
d+=x*2+3;
x++;
}
else
{
d+=(x-y)*2+5;
x++;y--;
}
circlePoint(x,y,xc,yc,color);
}
}


八分圆的绘制

void circlePoint(GLint x,GLint y,GLint xc,GLint yc,GLfloat *color)
{
setPixeli(xc+x,yc+y,color);
setPixeli(xc-x,yc+y,color);
setPixeli(xc+x,yc-y,color);
setPixeli(xc-x,yc-y,color);
setPixeli(xc+y,yc+x,color);
setPixeli(xc-y,yc+x,color);
setPixeli(xc+y,yc-x,color);
setPixeli(xc-y,yc-x,color);
}

(END)

版权声明:本文为博主原创文章,未经博主允许不得转载。

转载于:https://www.cnblogs.com/shonminh/p/4608397.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值