中点画圆法,是画圆形比较常用的一种算法。
第一点,我们可以确认画任意位置的圆,都可以先在坐标系原点画一个半径相同的圆,然后通过平移来得到这个原因。
第二点,y=x,y=-x,x=0,y=0这四条线是圆心在原点上的圆的对称线。所以我们只需画出横坐标X在区间【0,sqrt(2)*r】上的弧线即可根据圆的对称性来画出其他部分.
根据上面2点,只要画出以原点为中心X在区间【0,sqrt(2)*r】上的圆的一段弧,就可以画出任意大小,任意位置的圆。
圆的方程式 F(X,Y)=X^2+Y^2-R^2
以(0,0)为起点,(0,sqrt(2)*r)为终点画的狐,随着X增加,y不断减少。由于在计算机图形中,所有图形都是离散的,所以X轴上的每个整数坐标都对应着离圆弧最近的一点。
假设点P(Xp,Yp)是圆弧上的一点,下一个点的坐标是P1(Xp+1,Yp)或者P2(Xp+1,Yp-1)。圆弧离哪个点最近就取哪个点。中点画圆法的思想是。设一个点M事P1和P2的中点。如果F(X+1,M)<0,表示M点在圆内,则P1离圆弧更近,取(Xp+1,Yp),如果F(X+1,M)>0表示P2离圆弧更近,取(Xp+1,Yp-1)。
经过上面分析,设点(X,Y)是一个已经画出的点
得出,Dp=F(X+1,m)=F(X+1,Y-0.5)=(X+1)^2+(Y-0.5)^2-R^2
如果F(X+1,m)> 0 ,则下一个点 是(X+2,Y-1.5)
D(p+1) =F(X+2,Y-1.5)= F(X+1,M)+ 2(X-Y)+5=Dp+ 2(X-Y)+5
如果F(X+1,m)< 0 则下一个点 是(X+2,Y-0.5)
D(p+1) =F(X+2,Y-0.5)= Dp+ 2X+3
当F(X+1,m)= 0 取 (X+2,Y-1.5)
D的初始值=1.25-R
为了避免浮点运算设E=D-0.25=1-R。由于判别式Dp都是对整数做运算,所以减去0.25不影响正负关系。
所以 e>=0,
e= e+ 2(X-Y)+5
e<0 , e= e+ X+3
代码:
void DrawCircle(int r) //中点画圆法
{
int a=0,b=r;
int e=1-r;
glBegin(GL_POINTS);
while (a<=b)
{
glVertex2i(a,b);
glVertex2i(a,-b);
glVertex2i(-a,b);
glVertex2i(-a,-b);
glVertex2i(b,a);
glVertex2i(b,-a);
glVertex2i(-b,a);
glVertex2i(-b,-a);
a++;
if(e<0)
e+=2*a+3;
else
{
e+=2*(a-b)+5;
b--;
}
}
glEnd();
}