為了能以任意點為圓心畫圓,我們可以把圓心先設為視點(相當於於將其平移到坐標原點),然后通過中點法掃描轉換后,再恢復原來的視點(相當於將圓心平移回原來的位置)。
圓心位於原點的圓有四條對稱軸x=0,y=0,x=y和x=-y,從而圓上一點(x,y),可得到其關於四條對稱軸的七個對稱點,這稱為八對稱性,下面的函數就用來顯示(x,y)及其七個對稱點.
void CirclePoints(int x,int y,long color,CDC *pDC) { //第1象限 pDC->SetPixel(x,y,color); pDC->SetPixel(y,x,color); //第2象限 pDC->SetPixel(-x,y,color); pDC->SetPixel(-y,x,color); //第3象限 pDC->SetPixel(-y,-x,color); pDC->SetPixel(-x,-y,color); //第4象限 pDC->SetPixel(x,-y,color); pDC->SetPixel(y,-x,color); }
中點畫圓算法就是每部單位間隔取樣並且計算離圓最近的位置。在繼續之前,我這里補充一個關於圓對稱性的知識點,通過在圓中計算考慮使用對稱性計算開銷可以減小到原來的1/8。對稱性質原理:
(1)圓是滿足x軸對稱的,這樣只需要計算原來的1/2點的位置;
(2)圓是滿足y軸對稱的,這樣只需要計算原來的1/2點的位置;
(3)圓是滿足y = x or y = -x軸對稱的,這樣只需要計算原來的1/2點的位置;
通過上面三個性質分析得知,對於元的計算只需要分析其中1/8的點即可。
例如:分析出來目標點(x,y)必然存在(x,-y),(-x,y),(-x,-y),(y,x),(y,-x),(-y,x),(-y,-x)的另外7個點。
關於中心畫圓算法,通過計算x = 0到 x = y的1/8圓的范圍,然后通過對稱原理得到其他7/8個點的信息。
這里和Bresenham算法有很多相似之處,同樣有一個決定下一個位置的關鍵值P來做權衡處理。
在中點畫圓算法中,通過平移的方法將假設圓心在坐標原點,然后計算,最后再平移到真實原心位置。
如果我們構造函數 F(x,y)=x2+y2-R2,則對於圓上的點有F(x,y)=0,對於圓外的點有F(x,y)>0,對於圓內的點F(x,y)<0 。與中點畫線法一樣,構造判別式:
d=F(M)=F(xp+1,yp-0.5)=(xp+1)2+(yp-0.5)2-R2
若 d<0,則應取P1為下一象素,而且再下一象素的判別式為:
d=F(xp+2,yp-0.5)=(xp+2)2+(yp-0.5)2-R2=d+2xp+3
若d≥0,則應取P2為下一象素,而且下一象素的判別式為
d=F(xp+2,yp-1.5)=(xp+2)2+(yp-1.5)2-R2=d+2(xp-yp)+5
我們這里討論的第一個象素是(0,R),判別式d的初始值為:
d0=F(1,R-0.5)=1.25-R

中點畫圓算法內容:
1,輸入圓心位置和圓的半徑,得到圓周上的第一個點Point1;
(假設起始點為坐標原點,后面將通過坐標平移來處理非圓心在圓點)
2,計算決策關鍵參數的初始值,P = 5/4 - r;
3,在每個Xn的位置,從n = 0開始,更具決策值P來判斷:
如果P<0,下一個點的位置為(Xn+1,Yn);
並且執行P = P + 2*x+3;
如果P>=0,下一個點的位置為(Xn+1,Yn-1);
並且執行P = P + 2.0*(x-y)+5;
4,通過對稱原理計算其他7個對稱相關點;
5,移動坐標到圓心點(x1,y1)
X = X + x1;
Y = Y + y1;
6,如果X<Y重復執行3到5的步驟,否則結束該算法
程序如下:
void Circle::Draw(CDC *pDC) {//中點算法畫圓 int x,y; double p; pDC->SetViewportOrg(pMid); x=0; y=radis; p=1.25-radis; while(x<=y+1) { CirclePoints(x,y,m_lPenColor,pDC); x++; if(p>=0) { y--; p+=2.0*(x-y)+5; } else p+=2*x+3; } pDC->SetViewportOrg(0,0); }

原文地址:http://www.cnblogs.com/phinecos/archive/2007/07/28/834407.html
