Bresenham畫圓算法 與中點畫圓法


Bresenham畫圓算法

不失一般性,假設圓的圓心位於坐標原點(如果圓心不在原點,可以通過坐標平移使其與原點重合),半徑為R。以原點為圓心的圓C有四條對稱軸:x = 0, y = 0, x = y和x = -y。若已知圓弧上一點P1=C(x, y),利用其對稱性便可以得到關於四條對稱軸的其它7個點,即:

  P2=C(x,-y),

  P3=C(-x, y),

  P4=C(-x,-y),

  P5=C(y,x),

  P6=C(-y,x),

  P7=C(y,-x),

  P8=C(-y,-x)。

這種性質稱為八對稱性。

因此,只要掃描轉換八分之一圓弧,就可以通過圓弧的八對稱性得到整個圓。

【Bresenham算法】

    簡單圖形的掃描轉換常用算法是Bresenham算法。它的思想在於用誤差量來衡量點選取的逼近程度。其過程如下:

以平面二維圖形的掃描轉換為例,設要畫的圖形方程為F(x, y)=0,要畫的區域為[x0, x](不妨設x方向是最大位移方向,即△x > △y),則F(x,y) 也是一個誤差度量函數,我們拿離散的點值代入如果大於0則正向偏離,否則負向偏離,等於0的情況比較少,它表示的是不偏離即恰好與真實點重合。既然x是最大位移方向,那每次對x自增1,相應的y可以選擇不增或增1(或-1,具體問題具體分析),選擇的方法就是d = F(x + 1, y ± 0.5)的正負情況進行判斷從而選擇y的值。

實際情況中還要考慮到浮點數的計算問題,因為基本的圖形掃描轉換算法最好能夠硬件實現,所以擺脫浮點數是最好的,常用的方法是對d進行遞推,而不是直接由F(x,y)給出(直接給出速度會慢)。

 

【圓的掃描轉換算法】

    以畫圓為例,給出圓心的坐標(0, 0)和半徑R,求圓圖像的最佳逼近點。

圓是中心對稱的特殊圖形,所以可以將圓八等分,則只須對八分之一圓孤求解,其它圓孤可以由對稱變換得到,我們求的八分之一圓孤為(0, R) -(R√2,R√2),可知最大位移方向是x方向,x0 = 0, y0 = R,每次對x自增,然后判斷y是否減1,直到x >= y為止(從點(0, R)到圓的八分之一處就有這種情況)。誤差量由F(x, y) = x^2 + y^2 - R^2給出。

先找遞推關系,若當前d = F(x + 1, y - 0.5) > 0,則y須減1,則下一d值為

d =  F(x + 2, y - 1.5) = (x + 2)^2 + (y - 1.5)^2 - R^2 = (x + 1)^2 + (x - 0.5)^2 - R^2 + 2x + 3 - 2y + 2 = d + 2x - 2y + 5,若當前d = F(x + 1, y - 0.5) < 0,則y不變,只有x增1,則下一d值為d = F(x + 2, y - 0.5) = d + 2x + 3。

    d的初值,d0 = F(1, R - 0.5) = 1.25 - R,則可以對d - 0.25進行判斷,因為遞推關系中只有整數運算,所以d - 0.25 > 0即d > 0.25,這和d > 0等價,所以d取初值1 - R。

代碼:

bool CEnginApp::DrawCircle(ScPoint point,int radius,UNINT *vb_start,int lpitch)
{
    if (!vb_start||lpitch<=0)
        return false;

    int mx=point.x,my=point.y;
    int x=0,y=radius;

    int r=0,g=255,b=0;

    int d=1-radius;    //起點(0,R),下一點中點(1,R-0.5),d=1*1+(R-0.5)*(R-0.5)-R*R=1.25-R,d只參與整數運算,所以小數部分可省略

    while (y>x)    // y>x即第一象限的第1區八分圓
    {
        Plot_Pixel_32(x+mx,y+my,0,r,g,b,vb_start,lpitch);
        Plot_Pixel_32(y+mx,x+my,0,r,g,b,vb_start,lpitch);
        Plot_Pixel_32(-x+mx,y+my,0,r,g,b,vb_start,lpitch);
        Plot_Pixel_32(-y+mx,x+my,0,r,g,b,vb_start,lpitch);

        Plot_Pixel_32(-x+mx,-y+my,0,r,g,b,vb_start,lpitch);
        Plot_Pixel_32(-y+mx,-x+my,0,r,g,b,vb_start,lpitch);
        Plot_Pixel_32(x+mx,-y+my,0,r,g,b,vb_start,lpitch);
        Plot_Pixel_32(y+mx,-x+my,0,r,g,b,vb_start,lpitch);
        if (d<0)
        {
            d=d+2*x+3;
        }
        else
        {
            d=d+2*(x-y)+5;
            y--;
        }
        x++;
    }


    return true;
}

效果圖:

參考:

http://blog.csdn.net/cay22/article/details/5774628

http://www.cnblogs.com/phinecos/archive/2007/07/28/834407.html

http://dolphin-magstar.blogbus.com/logs/73759291.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM