グラフィックス・エントリ(2) - アーク生成アルゴリズム(中点drawcircle)

グラフィックス孟新しい学習記録。

完全な円あれば弧を描くように学習するプロセスを学習した後、線形アルゴリズムが生成され続け、再レンダリング点対称で別の象限に1つの象限を描画した後、これに、8つの対称性は、座標系を使用することができます。

我々は、第一円は、単に中心にオフセット算出された画素後の任意の時点で円を描く追加、半径rを有し、中央に原点を考えます。

円パラメトリック方程式を使用して計算され、最も暴力的な方法の円を描画するには:

 

 

 しかし、これは、三角関数を使用して浮動小数点演算を、非効率的な計算ので、私たちは通常、円に中間点drawcircleを使用しています。

中点drawcircle

中間点drawcircleブレゼンハムのアルゴリズムを使用すると、単純な整数演算を行い、判別選択されたピクセルを使用しての考え方に似ています。

、その後、次の点のいずれか右P1、いずれかの権利は、我々8つの象限の例として、円の1/8第二象限、画素が判定された場合($ X_ {P}、Y_ {P} $)であります以下P2。

 

コンストラクタ関数F(X、Y)= $ X ^ {2} $ + 1 $のY ^ {2} $ - $ R ^ {2} $、Fは0より大きく、円形で外側の円上の点、またはその逆である場合内部。

Mは=($ X_ {P} $ + 1、$のY_ {P} -0.5 $)、F(M)<0、Mが円に記載ときに図Mは、P1とP2の中間点でありますP1からより最近のアーク、M外円、P2に近い一方。

上記の原理によると、判別式を設定します:

 

 $ D_ {P} $ <0は、次の画素P1をとると、次の画素が式として決定されます。

 

 $ D_ {P} $> 0は、次の画素P2が取られたとき、次の画素は式のように決定されます。

 

 我々はオクタント時計回りに、第1のピクセル(0、R)を生成し、最初の判別式は次のとおりです。

 0.25を減算することにより、シンボルに影響を及ぼさないように、演算処理増分は、整数であるので、1.25-Rは、浮動小数点演算を除去し、1-Rに還元することができます。

コードは次のように実装されています。

ボイド CirclePoints(HDC、HDC、int型の Xは、int型 Y、INT OFFX、INT offy)を// 完全な円対称のビデオ使用
{ 
    とsetPixelを(HDC、X + OFFX、Y + offy、RGB(000 )); 
    とsetPixel (HDC、Y + OFFX、RGB、X + offy(000 )); 
    とsetPixel(HDC、X + OFFX、-Y + offy、RGB(000 )); 
    とsetPixel(HDC、 -Y OFFX +、X + offy、RGB(000)); 
    setPixel(HDC、 -x + OFFX、Y + offy、RGB(000 )); 
    setPixel(HDC、Y + OFFX、-x + offy、RGB(000 )); 
    setPixel(HDC、 -x + OFFX、-y + offy、RGB(000 )); 
    setPixel(HDC、 -y + OFFX、-x + offy、RGB(000 )); 
} 

ボイド MidPointCircle(HDCのHDC、INT X1、INT Y1、INT R)// 中点画圆
{
     int型X、Y、E。
    X = 0Y = R。E = 1 - R。
    CirclePoints(HDC、X、Y、X1、Y1)。
    一方、(x <= Y)
    { 
        場合(E < 0 
            E + = 2 * X + 3 
        { 
            E + = 2 *(x - y)は+ 5 
            Y - 
        } 
        xは ++ 
        CirclePoints(HDC、X、Y、X1、Y1)。
    } 
}

 

実行、Windowsのコードを実行します。

書式#include <はWindows.h> 
書式#include <iostreamの> 
の#include <cmath>
 使用して 名前空間はstd; 

const  int型 ScreenWidth = 500 ;
const  int型 ScreenHeight = 500 ; 

LRESULT CALLBACK WINPROC(HWNDのhWnd、UINTメッセージ、WPARAM wParamに、LPARAM lParamに)
{ 
    スイッチ(メッセージ){
     ケースWM_CLOSE:
        DestroyWindowを(のhWnd)。
        破ります;
    ケースWM_DESTROY:
        PostQuitMessage(0 )。
        破ります;
    デフォルトリターンDefWindowProc関数(hWndは、メッセージ、wParamに、lParamに)。
        破ります; 
    } 
    戻り 0 
} 

ボイド CirclePoints(HDCのHDC、int型のx、int型の Y、INT OFFX、INT offy)// 利用对称性画整圆
{ 
    とsetPixel(HDC、X + OFFX、Y + offy、RGB(000 )); 
    setPixel(HDC、Y + OFFX、X + offy、RGB(000 )); 
    setPixel(HDC、X + OFFX、-y + offy、RGB(000 )); 
    setPixel(HDC、 -y + OFFX、X + offy、RGB(000 )); 
    setPixel(HDC、 -x + OFFX、Y + offy、RGB(000 )); 
    setPixel(HDC、Y + OFFX、-x + offy、RGB(000 )); 
    setPixel(HDC、 -x + OFFX、-y + offy、RGB(000 )); 
    setPixel(HDC、 -y + OFFX、-x + offy、RGB(000 )); 
}

ボイド MidPointCircle(HDCのHDC、INT X1、INT Y1、INT R)
{ 
    int型、X、Y、E。
    X = 0Y = R。E = 1 - R。
    CirclePoints(HDC、X、Y、X1、Y1)。
    一方、(x <= Y)
    { 
        場合(E < 0 
            E + = 2 * X + 3 
        { 
            E + = 2 *(x - y)は+ 5 
            Y - 
        }
        バツ ++ ; 
        CirclePoints(HDC、X、Y、X1、Y1); 
    } 
} 

INT WINAPIのWinMain(hInstanceはHINSTANCE、HINSTANCE hPrevInstance、PSTR szCmdLine、int型nShowCmd)を
{ 
    WNDCLASS WCS; 
    wcs.cbClsExtra = 0 ;                                          // ウィンドウクラスの追加パラメータ   
    wcs.cbWndExtra = 0 ;                                          // ウィンドウの追加パラメータ   
    wcs.hbrBackground =(HBRUSH)GetStockObject(WHITE_BRUSH);     // ウィンドウDC背景   
    wcs.hCursor = LoadCursor(hInstanceは、IDC_CROSS);              // マウススタイル  
    wcs.hIcon = LoadIcon(NULL、IDI_WINLOGO)。                    // 窗口アイコン   
    wcs.hInstance = hInstanceは、                                  // 应用程序实例   
    wcs.lpfnWndProc = (WNDPROC)WINPROC。
    wcs.lpszClassName = " CG " 
    wcs.lpszMenuName = NULL; 
    wcs.style = CS_VREDRAW | CS_HREDRAW; 
    RegisterClass( WCS)。
    HWND hWndは、
    hWnd =のcreateWindow(" CG "" DrawCircle "、WS_OVERLAPPEDWINDOW、200200 、ScreenWidth、ScreenHeight、NULL、NULL、hInstanceは、NULL); 
    ShowWindow(hWndは、nShowCmd)。
    UpdateWindow(hWndを)
    MSGのMSG。

    // HDC INIT 
    HDC、HDC = GetDC(のhWnd); 

    MidPointCircle(HDC、200200150 )。

    // 消息循环   
    一方(のGetMessage(&MSG、0 、NULL、NULL)){ 
        TranslateMessage( MSG)。
        DispatchMessageを(MSG)。
    } 

    // 解放
    ReleaseDCの(hWndは、HDC)を、
    リターン 0 ; 
}
コードの表示

結果:

 

 

 次の領域充填アルゴリズム、給油は〜です

おすすめ

転載: www.cnblogs.com/LiveForGame/p/11718526.html