日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

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

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

(轉(zhuǎn)載自天極網(wǎng)的)很詳細(xì)的坐標(biāo)系的變換。

基于VC++的GDI常用坐標(biāo)系統(tǒng)及應(yīng)用

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

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


圖一、笛卡爾坐標(biāo)系

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

  圖二、代碼效果圖 

  按照同樣的原理,你可以使用CpaintDC的方法或按照你的要求創(chuàng)建函數(shù)來繪制任何幾何或非幾何圖形。例如,下面的代碼繪制了兩條相互垂直的直線,垂點(diǎn)位與窗口的中心:
 
void CExoDraw1View::OnPaint()   { CPaintDC dc(this); // 繪圖的設(shè)備上下文 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); // 得到客戶區(qū)域的尺寸; 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常用坐標(biāo)系統(tǒng)及應(yīng)用

2005-06-20 08:59作者:劉濤出處:天極網(wǎng)責(zé)任編輯:方舟
  三、更改坐標(biāo)系統(tǒng)
 
  
正如上面所看到的,默認(rèn)的坐標(biāo)系統(tǒng)坐標(biāo)原點(diǎn)位于窗口的左上角,水平軸的正方向向右,垂直軸的正方向向下。為了進(jìn)一步說明這一點(diǎn),讓我們來繪制一個半徑為50個單位,圓心位于(0,0)點(diǎn),同時繪制一個連接(0,0)(100,100)兩點(diǎn)的直線。
 
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); }

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

  需要注意的是,你也可以相對于客戶區(qū)域來指定坐標(biāo)原點(diǎn)
 
void CExoDraw1View::OnPaint()   { CPaintDC dc(this); //繪圖的設(shè)備上下文; CRect Recto; //獲取客戶區(qū)尺寸; 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); }

  圖六、代碼效果圖 

  現(xiàn)在你已了解了如何設(shè)置坐標(biāo)原點(diǎn),讓我們來將(380,220)點(diǎn)作為坐標(biāo)原點(diǎn),并繪制出笛卡爾的坐標(biāo)軸:
 
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); }

 圖七、代碼效果圖 

  正如已經(jīng)看到的,SetViewportOrg()函數(shù)可以更改設(shè)備上下文的坐標(biāo)原點(diǎn),同時,它也用來規(guī)定坐標(biāo)軸的正方向,即水平軸向右,垂直軸向下:

 圖八、坐標(biāo)軸示意圖 

  為了說明這一點(diǎn),下面來繪制一條黃色的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度位置,而是位于坐標(biāo)系統(tǒng)的第四象限,造成這種情況的原因是默認(rèn)的坐標(biāo)系統(tǒng)。
與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖

總結(jié)

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

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。