地區填充演算法__演算法

來源:互聯網
上載者:User

                                       地區填充演算法

一.目的:

   掌握有序編表法的基本原理與實現,瞭解簡單的互動技術。 二.要求:

    1.  邊界種子互動輸入;

    2.  執行個體包含有凹凸多邊形類型;

    3.  支援顏色選擇,圖案編輯。 三.內容:

    1.實現有序編表法;

    求出掃描線和多邊形每條邊的交點(x1,y1)的橫縱座標的最大最小值Xmin,Xmax,Ymax,Ymin。利用求出的每條邊交點橫縱座標的最大最小值編成一張從小到大排列的表(float m_yMax[N],m_yMin[N],m_Xa[N],m_Dx[N]),然後根據    這張表進行多邊形填充。其中的一些函數功能說明:

    void CCgFQlineDemoView::pFillScan(CDC* pDC)

    void FillPolygon(int n, CPoint *points, CDC *pDC)//編表法實現

    void pLoadPolygon(int pNumbers,CPoint *points)//多邊形載入

    void pInsertLine(float x1, float y1,float x2, float y2)//求交點

    void pInclude();

    void pUpdateXvalue();

    void pXsort(intBegin, int i)//建立有序表,即將各交點大小排序    2. 實現種子填充演算法:

        演算法原理:

     (1)棧頂象素出棧;

     (2)沿掃描線對出棧象素的左右象素進行填充,直至遇到邊界象素為止,即每出棧一個像素,就對包含該象素的整個區間進行填充;

     (3)上述區間內最左,最右的象素分別記為x1和x2;

     (4)在區間[x1,x2]中檢查與當前掃描線相鄰的上下兩條掃描線的有關象素是否全為邊界象素或已填充的象素,若存在非邊界,未填充的象素,則把每一區間的最右象素取作種子象素入棧。

      該演算法的實現函數為void ScanLineFill(CDC* pDC, CPoint point, int color0)

四.關鍵代碼:     (1)void CCgWP_FQlineDemoView::OnMouseMove(UINT nFlags,CPoint point) 

void CCgWP_FQlineDemoView::OnMouseMove(UINT nFlags, CPoint point) {// TODO: Add your message handler code here and/or call defaultif (m_pNumbers) {m_pDC->SetROP2(2);m_pDC->MoveTo(m_pAccord[m_pNumbers-1]);m_pDC->LineTo(m_mousePoint);m_mousePoint = point;m_pDC->MoveTo(m_pAccord[m_pNumbers-1]);m_pDC->LineTo(m_mousePoint);}CView::OnMouseMove(nFlags, point);}
     (2)void CCgWP_FQlineDemoView::OnLButtonDown(UINT nFlags,CPoint point) 

void CCgWP_FQlineDemoView::OnLButtonDown(UINT nFlags, CPoint point) {// TODO: Add your message handler code here and/or call default   CCgWP_FQlineDemoDoc* pDoc = (CCgWP_FQlineDemoDoc*) GetDocument();if( pDoc->SIGN){           if (m_pNumbers < N) {       m_pAccord[m_pNumbers] = point;       m_pNumbers++;       m_mousePoint = point;}}else{            m_tempPoint = point;    if( pDoc->SEEDFillMode)              CCgWP_FQlineDemoView::ScanLineFill(m_pDC, m_tempPoint,RGB(0,0,255));}CView::OnLButtonDown(nFlags, point);}

   (3)void CCgWP_FQlineDemoView::OnLButtonDblClk(UINT nFlags, CPointpoint) 

void CCgWP_FQlineDemoView::OnLButtonDblClk(UINT nFlags, CPoint point) {// TODO: Add your message handler code here and/or call default    CCgWP_FQlineDemoDoc* pDoc = (CCgWP_FQlineDemoDoc*) GetDocument();if(pDoc->SIGN){m_pDC->MoveTo(m_pAccord[m_pNumbers-1]);    m_pDC->LineTo(m_pAccord[0]);m_pAccord[m_pNumbers] = m_pAccord[0];m_pNumbers++; //此時的值為頂點數加上1sprintf( stringnumber, "%d", m_pNumbers-1 );m_pDC->TextOut(100,200,stringnumber);FillPolygon(m_pNumbers, m_pAccord, m_pDC);m_pNumbers = 0; // 防止滑鼠拖動時劃線CView::OnLButtonDblClk(nFlags, point);}}

 (4)void CCgWP_FQlineDemoView::FillPolygon(int n, CPoint *points, CDC*pDC)

void CCgWP_FQlineDemoView::FillPolygon(int n, CPoint *points, CDC *pDC){CCgWP_FQlineDemoDoc* pDoc = (CCgWP_FQlineDemoDoc*) GetDocument();m_edgeNumbers = 0;pLoadPolygon(n, points);//載入多邊形,通過記錄m_yMax[N],m_yMin[N],m_Xa[N],m_Dx[N]來記錄每一條邊m_Begin = m_End = 0;m_Scan = (int)m_yMax[0];pInclude(); // 求交pUpdateXvalue();//改變m_Xa[N]的值while (m_Begin != m_End) {pFillScan(pDC);m_Scan--;pInclude();pUpdateXvalue();}//當已經求交邊數和已經刪除的邊數不相等時,進入迴圈}

 (5)void CCgWP_FQlineDemoView::pLoadPolygon(intpNumbers,CPoint *points)

void CCgWP_FQlineDemoView::pLoadPolygon(int pNumbers,CPoint *points){float x1,y1,x2,y2;x1 = points[0].x;    y1 = points[0].y+0.5;for (int i = 1; i < pNumbers; i++) {        x2 = points[i].x;  y2 = points[i].y+0.5;if( y1-y2 )  pInsertLine(x1,y1,x2,y2);  x1 = x2; y1 = y2;}}

  (6) void CCgWP_FQlineDemoView::pInsertLine(floatx1, float y1,float x2, float y2)

 void CCgWP_FQlineDemoView::pInsertLine(float x1, float y1,  float x2, float y2){int i;float Ymax,Ymin;Ymax = (y2 > y1) ? y2 :  y1;Ymin = (y2 < y1) ? y2 : y1;i = m_edgeNumbers;while (i > 0 && Ymax > m_yMax[i-1]) {          m_yMax[i] = m_yMax[i-1];      m_yMin[i] = m_yMin[i-1];      m_Dx[i] = m_Dx[i-1];  m_Xa[i] = m_Xa[i-1];  i--;                                  }m_yMax[i] = Ymax;m_yMin[i] = Ymin;if (y2 > y1) m_Xa[i] = x2;else         m_Xa[i] = x1;m_Dx[i] = (x1 - x2) / (y2 - y1);m_edgeNumbers++;}

   (7) void CCgWP_FQlineDemoView::pInclude()

 void CCgWP_FQlineDemoView::pInclude(){while (m_End < m_edgeNumbers && m_yMax[m_End] > m_Scan) {        m_Xa[m_End] = m_Xa[m_End] - 0.5 * m_Dx[m_End];m_End++;}}

  (8) void CCgWP_FQlineDemoView::pUpdateXvalue()

void CCgWP_FQlineDemoView::pUpdateXvalue(){int i,start = m_Begin;for (i = start; i < m_End; i++) {if (m_Scan > m_yMin[i]) {m_Xa[i] += m_Dx[i];pXsort(m_Begin, i);} else { for (int j = i; j > m_Begin; j--) {m_yMin[j] = m_yMin[j-1];m_Xa[j] = m_Xa[j-1];m_Dx[j] = m_Dx[j-1];   }m_Begin++;}}}

  (9) void CCgWP_FQlineDemoView::pXsort(intBegin, int i)

void CCgWP_FQlineDemoView::pXsort(int Begin, int i){float temp;    while (i > Begin && m_Xa[i] < m_Xa[i-1]) {temp = m_Xa[i];        m_Xa[i] = m_Xa[i-1];m_Xa[i-1] = temp;temp = m_yMin[i];        m_yMin[i] = m_yMin[i-1];m_yMin[i-1] = temp;temp = m_Dx[i];        m_Dx[i] = m_Dx[i-1];m_Dx[i-1] = temp;i--;}}
   (10)voidCCgWP_FQlineDemoView::pFillScan(CDC* pDC)

void CCgWP_FQlineDemoView::pFillScan(CDC* pDC){int x=0,y=0;CCgWP_FQlineDemoDoc* pDoc = (CCgWP_FQlineDemoDoc*) GetDocument();    if( pDoc->SEEDFillMode == 0 ){pDC->SetROP2(10);for (int i = m_Begin; i < m_End; i += 2) {if (pDoc->SOLIDFillMode) {pDC->MoveTo(m_Xa[i],   m_Scan);pDC->LineTo(m_Xa[i+1], m_Scan);} else {  y = m_Scan;  for (int x = m_Xa[i]; x < m_Xa[i+1]; x++) if (m_patternData[y%7][x%6])pDC->SetPixel(x, y, RGB(0,0,255)); }}}}

  (11) void CCgWP_FQlineDemoView::OnRButtonDown(UINTnFlags, CPoint point) 

void CCgWP_FQlineDemoView::OnRButtonDown(UINT nFlags, CPoint point) {// TODO: Add your message handler code here and/or call defaultCCgWP_FQlineDemoDoc* pDoc = (CCgWP_FQlineDemoDoc*) GetDocument();pDoc->SIGN = !pDoc->SIGN;CView::OnRButtonDown(nFlags, point);}

  (12) void CCgWP_FQlineDemoView::ScanLineFill(CDC*pDC, CPoint point, int color0)

 void CCgWP_FQlineDemoView::ScanLineFill(CDC* pDC, CPoint point, int color0){CCgWP_FQlineDemoDoc* pDoc = (CCgWP_FQlineDemoDoc*) GetDocument();    int clr,color;int x,y,x0,y0,xl,xr,flag,xnextspan;iStack=0;pDC->SetROP2(10);x=point.x;y=point.y;y0=y;push(x,y);color=pDC->SetPixel(x,y,color0);while(iStack >0){pop(x,y);clr=pDC->SetPixel(x,y,RGB(255,0,255));x0=x+1;while(pDC->GetPixel(x0,y) !=color){pDC->SetPixel(x0,y,RGB(255,0,255));x0++;}xr=x0-1;// 最右像素x0=x-1;while(pDC->GetPixel(x0,y) !=color){pDC->SetPixel(x0,y,RGB(255,0,255));x0--;}xl=x0+1;// 最左像素x0=xl;y=y+1;while(x0<=xr){flag=0;while(pDC->GetPixel(x0,y) !=color &&   pDC->GetPixel(x0,y) !=clr &&  x0<xr){if(flag==0) flag=1;x0++;}if(flag==1){if(x0==xr && pDC->GetPixel(x0,y) !=color && pDC->GetPixel(x0,y) !=clr)push(x0,y);elsepush(x0-1,y);flag=0;}xnextspan=x0;while(pDC->GetPixel(x0,y) ==color ||   pDC->GetPixel(x0,y) ==clr &&  x0<=xr)  x0++;if(xnextspan==x0) x0++;}x0=xl;y=y-2;while(x0<=xr){flag=0;while(pDC->GetPixel(x0,y) !=color &&   pDC->GetPixel(x0,y) !=clr &&  x0<xr){if(flag==0) flag=1;x0++;}if(flag==1){if(x0==xr && pDC->GetPixel(x0,y) !=color && pDC->GetPixel(x0,y) !=clr)push(x0,y);elsepush(x0-1,y);flag=0;}xnextspan=x0;while(pDC->GetPixel(x0,y) ==color ||   pDC->GetPixel(x0,y) ==clr &&  x0<=xr)  x0++;if(xnextspan==x0) x0++;}}}

   (13)voidCCgWP_FQlineDemoView::push(int x, int y)

void CCgWP_FQlineDemoView::push(int x, int y){   if(iStack>1000)return;else{iStack++;stackX[iStack]=x;stackY[iStack]=y;}}

   (14)intCCgWP_FQlineDemoView::pop(int &x, int &y)

int CCgWP_FQlineDemoView::pop(int &x, int &y){if(iStack<=0) return -1;x=stackX[iStack];y=stackY[iStack];iStack--;return iStack;}<strong></strong>
五.結果及分析:    1. 有序編表法:     
   

  

  2.種子線掃描法:

    產生多邊形:

  


  


    通過比較可知:有序編表法效率更高,種子填充演算法更靈活。


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.