2014-01-06 126 views
0

當其半徑爲整數時,midpoint circle algorithm非常適合計算圓。什麼算法用於計算具有浮點半徑的圓?

void CircleOptimized(int xc, int yc, int r, int color) { 
    unsigned int x= r, y= 0;//local coords  
    int   cd2= 0; //current distance squared - radius squared 
    if (!r) return; 
    drawpixel(xc-r, yc, color); 
    drawpixel(xc+r, yc, color); 
    drawpixel(xc, yc-r, color); 
    drawpixel(xc, yc+r, color); 
    while (x > y) { //only formulate 1/8 of circle 
     cd2-= (--x) - (++y); 
     if (cd2 < 0) cd2+=x++; 
     drawpixel(xc-x, yc-y, color);//upper left left 
     drawpixel(xc-y, yc-x, color);//upper upper left 
     drawpixel(xc+y, yc-x, color);//upper upper right 
     drawpixel(xc+x, yc-y, color);//upper right right 
     drawpixel(xc-x, yc+y, color);//lower left left 
     drawpixel(xc-y, yc+x, color);//lower lower left 
     drawpixel(xc+y, yc+x, color);//lower lower right 
     drawpixel(xc+x, yc+y, color);//lower right right 
    } 
} 

例如,通過r=1時和r=2的輸出分別被如下:

..... .XXX. 
..X.. X...X 
.X.X. X...X 
..X.. X...X 
..... .XXX. 
r=1 r=2 

然而,我需要r=1r=2之間的幾個步驟。也許,(假設)r=1.33r=1.66這可能是這樣的:

..... ..... ..X.. .XXX. 
..X.. .XXX. .X.X. X...X 
.X.X. .X.X. X...X X...X 
..X.. .XXX. .X.X. X...X 
..... ..... ..X.. .XXX. 
r=1.0 r=1.3 r=1.6 r=2.0 

然而,當我試着去適應上述算法使用浮點運算(使用或不四捨五入),它失去了它的對稱性,併產生不連續的路徑(導致一些非常奇怪的形狀)。

有沒有更適合我的目的的算法?

+2

所以,你問爲什麼你不*顯示的代碼版本不起作用?在這裏看到任何問題? ;-) – hyde

+0

無論如何,這整個算法是基於整數算術。可以使用具有縮放的整數,也可以使用圓的基本* sin *和* cos *公式。 – hyde

+0

@hyde複製和粘貼代碼塊代替'float',然後再添加一個'round'複製並粘貼,看起來非常簡單。 –

回答

2

如果你只是簡單的分數(如4/3和5/3)感興趣的話,我會過採樣(即使用子像素,這裏9子每個像素,因此計算半徑爲4和5的子像素),然後從子像素中推導出一個良好的像素值。如果你推斷出除ON之外的其他內容,則表明你正在進行反走樣。

0

基本圓形繪圖...

public void DrawCircle(float stepSize, float radius, int colour) 
{ 
    float x, y; 
    float angle; 

    while (angle < 2*Math.PI) 
    { 
     x = radius * cos(angle); 
     y = radius * sin(angle); 
     // decide how to round your floating point X,Y here ... 
     drawpixel(x,y,colour); 
     angle += stepSize; 
    } 
} 
+1

尋找「步驟」和「決定如何輪迴」是兩個最大的問題。解決它們會比調整中點圓算法methink更成問題。 – Sinatr

+0

那麼,'step'就是你希望你的圈子有多光滑 - 如果你擔心你的圈子尺寸太多,你可以根據你的半徑想出一個縮放步驟。只要你決定如何輪迴是一致的(例如總是舍入),那麼你將不會得到用中點圓算法得到的斷開段。 – Mashton

+0

如果你採取的步驟太小,或者你的決定沒有考慮最近像素的決定 - 你最終一次繪製2個圓圈:刪除部分和四捨五入(例如,對於1.3它將是1和2)。尋找適當的步驟和四捨五入的決定是挑戰。嘗試自己畫一個小圓圈。我並不是說你的回答是錯誤的,這是正確的,但它太籠統了,可能不適合某個問題^^ – Sinatr

0

我認爲泰勒近似可能是有用的

  • 使用一階泰勒近似計算以x^2 = R^2- Y 1 2 X(SQRT(U^2 +α)= U + a/2u)