日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

基于VC++的GDI常用坐标系统及应用

發布時間:2025/3/20 c/c++ 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于VC++的GDI常用坐标系统及应用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

(轉載自天極網的)很詳細的坐標系的變換。

基于VC++的GDI常用坐標系統及應用

2005-06-20 08:59作者:劉濤出處:天極網責任編輯:方舟 在Windows應用程序中,只要進行繪圖,就要使用GDI坐標系統。Windows提供了幾種映射方式,每一種映射都對應著一種坐標系。例如,繪制圖形時,必須給出圖形各個點在客戶區的位置,其位置用x 和y兩個坐標表示,x 表示橫坐標,y表示縱坐標。在所有的GDI繪制函數中,這些坐標使用的是一種“邏輯單位”。當GDI函數將結果輸出送到某個物理設備上時,Windows將邏輯坐標轉換成設備坐標(如屏幕或打印機的像素點)。本文討論了圖形環境中的各個映射模式,包括它們是什么,怎么工作的,以及它們真正的含義。

  一、基礎知識
 
  (一)邏輯坐標。邏輯坐標與設備無關,缺省地,一個邏輯單位等于設備中的一個象素。它是實現“所見即所得”的基礎。例如,當程序員調用LineTo函數繪制25.4mm(1 英 寸) 長的直線時,他只要使用合適的映射模式,那么就并不需要考慮輸出的是何種設備。若設備是VGA顯示器,Windows自動將其轉化為96個像素點;若設備是一個300dpi的激光打印機,Windows自動將其轉化為300 個像素點。    (二)設備坐標。圖形輸出時,Windows將GDI函數中指定的邏輯坐標映射為設備坐標,在所有的設備坐標系統中,單位以像素點為準,水平值從左到右增大(正方向向右),垂直值從上到下增大(正方向向下)。Windows中包括以下3 種設備坐標,以滿足各種不同需要:    1、客戶區域坐標,包括應用程序的客戶區域,客戶區域的左上角為(0, 0)。    2、屏幕坐標,包括整個屏幕,屏幕的左上角為(0, 0)。屏幕坐標用在WM_MOVE消息中(對于非子窗口)以及下面的Windows 函數中:CreateWindow 和MoveWindow(都對于非子窗口)、GetMessage、GetCursorPos、GetWindowRect、WindowFromPoint 和SetBrushOrg 中。 用函數ClientToScreen 和ScreenToClient可以將客戶區域坐標轉換成屏幕區域坐標,或反之。 
 
  3、全窗口坐標,包括一個程序的整個窗口,包括標題條、菜單、滾動條和窗口框,窗口的左上角為(0,0)。使用GetWindowDC得到的窗口設備環境,可以將邏輯單位轉換成窗口”坐標。  
  (三)映射。映射方式定義了Windows如何將GDI函數中指定的邏輯坐標映射為設備坐標。在下文中我們將介紹常用的映射方式。   此外,習慣上,我們將邏輯坐標所在的坐標系稱為“窗口”;將設備坐標所在的坐標系稱為“視口”。“窗口”依賴于邏輯坐標,可以是像素點、毫米或其他尺度。這一點請牢記,這對于下面的有關內容的理解至關重要。     二、默認的坐標系統
 
  當在微軟的窗口中進行繪圖時,繪圖的坐標原點在屏幕的左上角,任何物體在屏幕上定位都要參考這個坐標原點。在笛卡爾坐標系統中這個點被定義為坐標原點(0,0),水平坐標軸的正方向是從該點出發向右延伸,垂直坐標軸的正方向是從該點出發向下延伸。


圖一、笛卡爾坐標系

  這個坐標原點只是操作系統默認的坐標原點,所以如果你調用Ellipse(-100, -100, 100, 100)函數來繪制圖形的話,你將得到一個圓,它的圓心位于屏幕的左上角,僅僅只有圓的四分之一部分(270度到360度的部分)顯示在屏幕上。代碼及效果圖如下 
void CExoDraw1View::OnPaint()  { CPaintDC dc(this); // 繪圖的設備廠上下文 CPen PenBlue; // 蘭色畫筆 PenBlue.CreatePen(PS_SOLID, 1, RGB(0, 12, 255)); dc.SelectObject(&pPen); dc.Ellipse(-100, -100, 100, 100); }

  圖二、代碼效果圖 

  按照同樣的原理,你可以使用CpaintDC的方法或按照你的要求創建函數來繪制任何幾何或非幾何圖形。例如,下面的代碼繪制了兩條相互垂直的直線,垂點位與窗口的中心:
 
void CExoDraw1View::OnPaint()   { CPaintDC dc(this); // 繪圖的設備上下文 CRect Recto; CPen PenBlue; PenBlue.CreatePen(PS_SOLID, 1, RGB(0, 12, 255)); dc.SelectObject(&PenBlue); dc.Ellipse(-100, -100, 100, 100); CPen PenBlack; PenBlack.CreatePen(PS_SOLID, 1, BLACK_PEN); dc.SelectObject(&PenBlack); // 得到客戶區域的尺寸; GetClientRect(&Recto); dc.MoveTo(Recto.Width() / 2, 0); dc.LineTo(Recto.Width() / 2, Recto.Height()); dc.MoveTo(0, Recto.Height() / 2); dc.LineTo(Recto.Width(), Recto.Height() / 2); }
   圖三、代碼效果圖 

基于VC++的GDI常用坐標系統及應用

2005-06-20 08:59作者:劉濤出處:天極網責任編輯:方舟
  三、更改坐標系統
 
  
正如上面所看到的,默認的坐標系統坐標原點位于窗口的左上角,水平軸的正方向向右,垂直軸的正方向向下。為了進一步說明這一點,讓我們來繪制一個半徑為50個單位,圓心位于(0,0)點,同時繪制一個連接(0,0)(100,100)兩點的直線。
 
void CExoDraw1View::OnPaint()  { CPaintDC dc(this); // device context for painting // A circle whose center is at the origin (0, 0) dc.Ellipse(-50, -50, 50, 50); // A line that starts at (0, 0) and ends at (100, 100) dc.MoveTo(0, 0); dc.LineTo(100, 100); }

圖四、代碼效果圖
  這種默認的坐標原點在大多數圖形操作情況下是適用的,但并不是總適用,有時你需要控制坐標系統的原點,例如,很多CAD(圖形輔助設計)應用程序就需要用戶來定義坐標系統的原點。
    MFC提供了各種函數來處理坐標定位及擴展繪制區域的問題,包括在屏幕上任意位置設置坐標原點的函數。因為你是在一個設備上下文上進行繪圖操作,因此,你所需要做的就是調用CDC::SetViewportOrg()函數。這個函數重載了兩個版本,這允許你使用X、Y坐標或是一個定義的Point點。這個函數的語法如下:
 
SetViewportOrg(int X, int Y); SetViewportOrg(CPoint Pt);
  調用這個函數時只需要簡單地說明哪兒是你想定義的坐標原點,如果使用函數的第二個版本,參數可以是一個POINT結構或是一個MFC提供的Tpoint類。為了演示這個函數的效果,讓我們將上例的坐標原點沿X軸正方向移動200個單位,Y軸正方向移動150個單位,這時繪制函數如下:  
void CExoDraw1View::OnPaint()  { CPaintDC dc(this); //繪圖的設備上下文; dc.SetViewportOrg(200, 150); // 圓心位于坐標原點(0, 0) dc.Ellipse(-50, -50, 50, 50); // 連接(0, 0) 和 (100, 100)點的直線; dc.MoveTo(0, 0); dc.LineTo(100, 100); }
 
 
 圖五、代碼效果圖
 

  需要注意的是,你也可以相對于客戶區域來指定坐標原點
 
void CExoDraw1View::OnPaint()   { CPaintDC dc(this); //繪圖的設備上下文; CRect Recto; //獲取客戶區尺寸; GetClientRect(&Recto); dc.SetViewportOrg(Recto.Width() / 2, Recto.Height() / 2); // A circle whose center is at the origin (0, 0) dc.Ellipse(-50, -50, 50, 50); // A line that starts at (0, 0) and ends at (100, 100) dc.MoveTo(0, 0); dc.LineTo(100, 100); }

  圖六、代碼效果圖 

  現在你已了解了如何設置坐標原點,讓我們來將(380,220)點作為坐標原點,并繪制出笛卡爾的坐標軸:
 
void CExoDraw1View::OnPaint()   { CPaintDC dc(this); // device context for painting CRect Recto; dc.SetViewportOrg(380, 220); // Use a red pen CPen PenRed(PS_SOLID, 1, RGB(255, 0, 0)); dc.SelectObject(PenRed); // A circle whose center is at the origin (0, 0) dc.Ellipse(-100, -100, 100, 100); // Use a blue pen CPen PenBlue(PS_SOLID, 1, RGB(0, 0, 255)); dc.SelectObject(PenBlue); // Horizontal axis dc.MoveTo(-380, 0); dc.LineTo(380, 0); // Vertical axis dc.MoveTo(0, -220); dc.LineTo(0, 220); }

 圖七、代碼效果圖 

  正如已經看到的,SetViewportOrg()函數可以更改設備上下文的坐標原點,同時,它也用來規定坐標軸的正方向,即水平軸向右,垂直軸向下:

 圖八、坐標軸示意圖 

  為了說明這一點,下面來繪制一條黃色的45度角的直線:  
void CExoDraw1View::OnPaint()  { CPaintDC dc(this); // device context for painting dc.SetViewportOrg(380, 220); // Use a red pen CPen PenRed(PS_SOLID, 1, RGB(255, 0, 0)); dc.SelectObject(PenRed); // A circle whose center is at the origin (0, 0) dc.Ellipse(-100, -100, 100, 100); // Use a blue pen CPen PenBlue(PS_SOLID, 1, RGB(0, 0, 255)); dc.SelectObject(PenBlue); // Horizontal axis dc.MoveTo(-380, 0); dc.LineTo(380, 0); // Vertical axis dc.MoveTo(0, -220); dc.LineTo(0, 220); // An orange pen CPen PenOrange(PS_SOLID, 1, RGB(255, 128, 0)); dc.SelectObject(PenOrange); // A diagonal line at 45 degrees dc.MoveTo(0, 0); dc.LineTo(120, 120); }

 圖九、代碼效果圖 

  正如你所看到的,我們的直線沒有在45度位置,而是位于坐標系統的第四象限,造成這種情況的原因是默認的坐標系統。
與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的基于VC++的GDI常用坐标系统及应用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。