2012-12-28 140 views
3

我想畫一個圓,我目前正在使用Ellipse()函數。Win32 GDI畫一個圓圈?

我有鼠標的起始座標 - x1和y1以及結束座標x2和y2。正如你所看到的,我迫使y2(temp_shape.bottom)= y1 +(x2-x1)。這不符合預期。我知道這個計算是完全錯誤的,但是對於什麼是正確的?

代碼如下。

case WM_PAINT: 
     { 

      hdc = BeginPaint(hWnd, &ps); 
      // TODO: Add any drawing code here... 
      RECT rect; 
      GetClientRect(hWnd, &rect); 

      HDC backbuffDC = CreateCompatibleDC(hdc); 

      HBITMAP backbuffer = CreateCompatibleBitmap(hdc, rect.right, rect.bottom); 

      int savedDC = SaveDC(backbuffDC); 
      SelectObject(backbuffDC, backbuffer); 
      HBRUSH hBrush = CreateSolidBrush(RGB(255,255,255)); 
      FillRect(backbuffDC,&rect,hBrush); 
      DeleteObject(hBrush); 



      //Brush and Pen colours 
      SelectObject(backbuffDC, GetStockObject(DC_BRUSH)); 
      SetDCBrushColor(backbuffDC, RGB(255,0,0)); 
      SelectObject(backbuffDC, GetStockObject(DC_PEN)); 
      SetDCPenColor(backbuffDC, RGB(0,0,0)); 



      //Shape Coordinates 
      temp_shape.left=x1; 
      temp_shape.top=y1; 
      temp_shape.right=x2; 
      temp_shape.bottom=y2; 



      //Draw Old Shapes 
      //Rectangles 
      for (int i = 0; i < current_rect_count; i++) 
      { 
       Rectangle(backbuffDC, rect_list[i].left, rect_list[i].top, rect_list[i].right, rect_list[i].bottom); 
      } 
      //Ellipses 
      for (int i = 0; i < current_ellipse_count; i++) 
      { 
       Ellipse(backbuffDC, ellipse_list[i].left, ellipse_list[i].top, ellipse_list[i].right, ellipse_list[i].bottom); 
      } 

      if(mouse_down) 
      { 
       if(drawCircle) 
       { 

        temp_shape.right=y1+(x2-x1); 

        Ellipse(backbuffDC, temp_shape.left, temp_shape.top, temp_shape.right, temp_shape.bottom); 
       } 

       if(drawRect) 
       { 
        Rectangle(backbuffDC, temp_shape.left, temp_shape.top, temp_shape.right, temp_shape.bottom); 
       } 

       if(drawEllipse) 
       { 
        Ellipse(backbuffDC, temp_shape.left, temp_shape.top, temp_shape.right, temp_shape.bottom); 
       } 
      } 

      BitBlt(hdc,0,0,rect.right,rect.bottom,backbuffDC,0,0,SRCCOPY); 
      RestoreDC(backbuffDC,savedDC); 

      DeleteObject(backbuffer); 
      DeleteDC(backbuffDC); 
      EndPaint(hWnd, &ps); 
     } 
     break; 
+1

您能否給予更多的「不按預期工作」? – chris

+0

它沒有畫出一個正確的圓圈。 – user1788175

+0

@ user1788175:它畫的是什麼? – AnT

回答

1

我已經制定了哪些效果更好的計算。下面貼上了其他人想要的一樣。

if(drawSquare) 
       { 

        int xdiff = abs(x2-x1); 
        int ydiff=abs(y2-y1); 

        if(xdiff>ydiff) 
        { 
         if(y2>y1) 
          temp_shape.bottom=y1+xdiff; 
         else 
          temp_shape.bottom=y1-xdiff; 
        } 
        else 
        { 
         if(x2>x1) 
          temp_shape.right=x1+ydiff; 
         else 
          temp_shape.right=x1-ydiff; 
        } 


        Rectangle(backbuffDC, temp_shape.left, temp_shape.top, temp_shape.right, temp_shape.bottom); 
       } 
-2

您的代碼對於臨時DC和後臺緩衝區來說是不必要的複雜,並且您正在每個WM_PAIT中重新創建GDI畫筆?但那不是重點。這裏是一個問題:你爲什麼這樣做:

temp_shape.right=y1+(x2-x1); //basing horizontal coordinate on vertical? 

這是什麼框架堆棧? .NET,那你爲什麼不使用內置的雙緩衝?

+0

謝謝,對於複雜性感到抱歉。我不允許使用內置的雙緩衝。 我想在那裏可能需要一個計算來得到一個正確的圓,我目前正在計算出來。這是其中一項試驗。 – user1788175

2

如果你想要Ellipse()繪製一個完美的圓形圓,你需要給它一個完美的正方形形狀,而不是矩形形狀的座標。

假設x1,y1是拖動的起點座標和x2,y2是當前鼠標的座標,那麼試試這個:

//Shape Coordinates 
temp_shape.left = min(x1, x2); 
temp_shape.top = min(y1, y2); 
temp_shape.right = max(x1, x2); 
temp_shape.bottom = max(y1, y2); 

... 

if (drawCircle) 
{ 
    int length = min(abs(x2-x1), abs(y2-y1)); 

    if (x2 < x1) 
     temp_shape.left = temp_shape.right - length; 
    else 
     temp_shape.right = temp_shape.left + length; 

    if (y2 < y1) 
     temp_shape.top = temp_shape.bottom - length; 
    else 
     temp_shape.bottom = temp_shape.top + length; 

    Ellipse(backbuffDC, temp_shape.left, temp_shape.top, temp_shape.right, temp_shape.bottom); 
} 
+0

感謝這項工作,但如果鼠標從左下角拖到右上角或從右上角拖動到左下角,則不起作用。任何與積極/消極有關的事情? – user1788175

+0

您將不得不跟蹤拖動的起始座標,以便找出需要調整相對於繪圖座標的'temp_shape'的哪個角落。 –

+0

我用一些更多的計算更新了我的答案。 –