bresenham演算法畫圓思想與上篇 bresenham演算法畫線段 思想是一致的
畫圓x^2+y^2=r^2
將他分為8個部分,如上圖
1.只要畫出1中1/8圓的圓周,剩下的就可以通過對稱關係畫出這個圓
x變化從0->r
那為什麼不採用從-r->r呢,
y=+-sqrt(r^2-x^2);
dy/dx=-x/(sqrt(r^2-x^2)) =-x/y
所以採用從-r到r,每次橫座標增1,計算量大,而且在(x=+-r,y=0)處,x的很小變化就引起了y的很大變化。
所以不是採用x從-r--->r變化。而是採用1/8畫圓法。
2.在2這1/8圓周上,x值單調增加,y值單調遞減,且fabs(dx/dy)=fabs(-x/y)<=1;所以圓周上相應點的y值變化小於1.
假設當前點為(x1,y1)這下個點為(x1+1,y1)或(x1+1,y1-1)
d1=(x1+1)^2+y1^2-r^2;
d2=r^2-(x1+1)^2-(y1-1)^2;
p=d1-d2 若p>0 選點(x1+1,y1-1)否則選點(x1+1,y1)
p=2(x1+1)^2+2y1^2-2y1-2r^2+1
接下來就是求p了。
p1=3-2r(座標為x=0,y=r)
然後仿照線段演算法得出p(i+1)=p(i)+4(xi-yi)+10(pi>0)否則p(i+1)=p(i)+4xi+6
這樣就可以成功畫出1/8圓弧了
3.接下來的問題,是剩下的部分怎麼處理,
有兩種方法:
方法一:儲存器將前1/8的座標儲存起來,然後通過映象求出其他圓弧座標,調整順序輸出,即可得到。
方法二:分別求出對應的8個圓弧的演算法式,一次畫弧。
演算法比較:前者演算法比較簡單,但是儲存資料,需要較大的ram,一旦在計算高精度,大半徑的圓時,資料儲存量就比較大,可能就需要擴充ram。後者**比較多,占用較多的程式儲存空間。
然後從控制理論角度考慮:前者是先計算後執行,實時性比較差,後者運算和控制交叉進行。但不會減少總時間。
綜上所述,當圓的精度低時,可以採用方法一。當圓精度高,半徑大,或者對運動過程中實時性要求比較高時,採用方法二。
在實際的實現過程中,發現按照方法二實現,圓無法畫整。因為每次後面1/8圓弧都是與前面的1/8圓弧最好乙個點相接的,這樣累積下來,勢必造成首尾無法相接,最後是採用方法一和方法二結合實現方法二的,即畫一半圓,然後利用對稱性實現的【即方法一的思想】。
方法一**實現:
方法二**是實現:
說明:上述**實現均是基於stm32處理器,tftlcd2.8寸屏上實現的
關於p的求法如果有疑問,可以參考上篇文章基於bresenham和dda演算法畫線段
對於屏上畫點,對各座標點賦值有疑問的可以參考這篇資料看看bresenham直線演算法與畫圓演算法
下面兩幅圖,是方法二實現的兩種比較,如果採用單一的 畫8個圓弧,會出現累積誤差,圓無法閉合。
圖1
圖 2
Bresenham演算法畫圓
下面先簡要介紹常用的畫圓演算法 bresenham演算法 然後再具體闡述筆者對該演算法的改進。乙個圓,如果畫出了圓上的某一點,那麼可以利用對稱性計算餘下的七段圓弧 plot x,y plot y,x plot y,x plot x,y plot x,y plot y,x plot y,x plot ...
中點Bresenham畫圓
這裡不仔細講原理,只是把我寫的演算法發出來,跟大家分享下,如果有錯誤的話,還請大家告訴我,如果寫的不好,也請指出來,一起討論進步。演算法步驟 1 輸入圓的半徑r。2 計算初始值d 1 r,x 0 y r。3 繪製點 x,y 及其在八分圓中的另外7個對稱點。4 判斷d的符號,若d 0,則先將d更新為d...
利用Bresenham演算法畫圓和直線
利用bresenham演算法,從零開始實現在矩陣中畫圓和直線,效果如下 close all clear all clc create image reactangle img ones 100 200 figure name original image imshow img draw line h...