圓的特征
圓被定義為給定中心位置(xp,yp)的距離為 r 的點集。圓心位於原點的圓有4條對稱軸。
- x=0
- x=y
- x=-y
- y=0
若已知圓弧上一點(x,y),可以得到其關於4條對稱軸的其他7個點,這種性質被稱為八對稱性。
因此只要掃描轉換1/8圓弧,就可以用八對稱性求出整個圓弧的像素集。
中點畫圓法
構造函數 F(x,y) = x2 + y2 - R2,如果點在圓內,F<0;否則,F > 0。
對於初始點(xp,yp),需要考慮的是中點 M(xp+1,yp-0.5),即 F(M)=(xp+1)2+(yp-0.5)2 - R2。(給定點 [0, r],則 d=1.25-r)
(1)若 d<0, 即中點在圓內,目標點在在上半格,而且下一個判別式 d1=F(xp+2, yp-0.5)= d+2xp+3。
(2)若 d>0, 即中點在圓外,目標點在下半格,而且下一個判別式 d2 = F(xp+2, yp-1.5)= d+2(xp-yp)+5。
1 // 偽代碼 2 void MidPointCircle(int r) { 3 int x, y; 4 float d; 5 x = 0; y = r; 6 d = 1.25 - r; 7 draw(x, y); 8 while (x <= y) { 9 if (d < 0) 10 d += 2*x+3; 11 else 12 {d+=2*(x-y)+5; y--;} 13 x++; 14 draw(x, y); 15 } 16 }
效果如下:

完整代碼
1 import numpy as np 2 import matplotlib.pyplot as plt 3 from matplotlib.ticker import MultipleLocator 4 5 def MidPointCircle(r): 6 x = 0; y = r 7 d = 1.25 - r 8 a = [x]; b = [y] 9 while x <= y: 10 if d < 0: 11 d += 2*x+3 12 else: 13 d += 2*(x-y)+5 14 y -= 1 15 x += 1 16 a.append(x) 17 b.append(y) 18 # 利用對稱性把其余七個八分圓補全 19 for i in range(len(a)): 20 a.append(b[i]) 21 b.append(a[i]) 22 for i in range(len(a)): 23 a.append(a[i]) 24 b.append(-b[i]) 25 for i in range(len(a)): 26 a.append(-a[i]) 27 b.append(b[i]) 28 plt.scatter(a, b, color='r') 29 30 31 # 畫圓 32 ax = plt.figure().add_subplot(111) 33 ax.set_xlim(-25, 25) 34 ax.set_ylim(-25, 25) 35 ax.xaxis.grid(True) 36 ax.yaxis.grid(True) 37 ax.xaxis.set_major_locator(MultipleLocator(1)) 38 ax.yaxis.set_major_locator(MultipleLocator(1)) 39 x = y = np.arange(-25, 25, 0.1) 40 x, y = np.meshgrid(x, y) 41 plt.contour(x, y, x**2+y**2, [400]) 42 43 MidPointCircle(20) 44 45 plt.show()
