1.圆的两个简单生成算法
其中 (xc,yc)为圆心坐标,变换上述方程,得到:
于是我们可以通过扫描 (xc−r,xc+r)区间上对应的点在屏幕上绘出圆来。但是这种方法虽然简单,但是效率低下。
另一种方法是考虑极坐标来表示圆的方程,方程组:
实现代码:
上述代码确实可行,但是引入三角函数来计算有点耗时。
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=0到x=y的圆弧段,圆上任一点P_i(xi,yi),那么下一个像素的选择就在集合{E,SE}中选择。对于E和SE的中点M点,构造一个M点和圆的方程的位置函数:
则 fM(x,y)有三种可能的情况,
将 M(xi+1,yi−12)代入 fM(x,y)方程中,有
若 dold<0,则选 E点,下一个中点 M′对应的 fM(x,y)值为
∴增量ΔE=dnew−dold=2xi+3.
同理, dold>0,则选择SE点,下一个中点M′对应的fM(x,y)值为
∴增量ΔE=dnew−dold=2xi−2yi+5.
由于圆的起始位置为 (0,r),第一个中点坐标为 (1,r−12),
则 d=fM(1,r−12)=1+(r2−r+14)−r2=54−r.注意到在实际计算时 x,y的增量都为整数,我们可以令初始值 d=1−r,这并不会改变 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)
版权声明:本文为博主原创文章,未经博主允许不得转载。