MFC GDI座標對映例解

2021-08-24 22:47:56 字數 3098 閱讀 1202

(1)建立單文件mfc專案draw:new

àprojectsàà

single document。

(2)找到cmainframe::precreatewindow函式,在其中設定預設視窗大小為400 pixel*300 pixel。

bool cmainframe::precreatewindow(createstruct& cs)

(3)新增onpaint事件

資源管理器à

classview

à右擊cdrawview

選擇add windows message handler à

wm_paint

àadd handler 1.

void

cdrawview::onpaint() 2.

執行結果如圖1左。當改變視窗大小時,圖中圓形狀始終不變。

<1>將上面**的第9行改為:dc.setmapmode(mm_anisotropic);//x!=y

執行結果如圖1右。

我們發現,儘管上面**的第13行dc.ellipse(-200,200,200,-200);中定義的橢圓外接矩形邏輯上為正方形,但是顯示的並不是圓,而是橢圓。

當我們改變視窗大小時,圖中橢圓變形,甚至可能變為圓形。具體為:

保持視窗寬度不變時,減小高度,橢圓變得更扁;保持視窗高度不變時,減小寬度,橢圓變得更圓,當拉伸到客戶區為正方形時,我們發現橢圓變成了圓!

<2>將上面**的第9行改回dc.setmapmode(mm_isotropic);//x=y

,第15行改為dc.lineto(500,0); 第18行改為dc.lineto(0,-500); 執行結果如圖2左。

保持視窗高度不變,減小視窗寬度,使視窗寬度視窗高度,執行結果如圖2右。

<3>在將<2>中**的第9行改回dc.setmapmode(mm_anisotropic);//x!=y

,執行結果如圖3:

當我們改變視窗大小時,dc.lineto(500,0); dc.lineto(0,-500);都是由原點(客戶區中心)到客戶區右端中心、底端中心的直線。

<4>將原**中第10行dc.setwindowext(1000,1000);//

設定邏輯視窗後新增dc.setwindoworg(100,100);設定邏輯視窗的原點為(100,100)。觀察執行結果可知,圖1中的圖形整體向左向下分別移動了100個邏輯單位:

(-200,200,200,-200)——>(-200-100,200-100,200-100,-200-100)

若需要保持圖1中的圖形,則需要將涉及到的每個點加上(100,100),即:

13.dc.ellipse(-200+100,200+100,200+100,-200+100);

14.//繪製水平垂直的四條半徑

15.dc.moveto(0+100,0+100); dc.lineto(200+100,0+100);

16.dc.moveto(0+100,0+100); dc.lineto(-200+100,0+100);

17.dc.moveto(0+100,0+100); dc.lineto(0+100,200+100);

18.dc.moveto(0+100,0+100); dc.lineto(0+100,-200+100)

(4)總結邏輯視窗座標到裝置視口座標的對映方法:

<1>邏輯視窗原點對映為視口原點

<2>邏輯視窗寬度和高度對映為視口寬度和高度

<3>當對映方式為mm_isotropic時,windowext.width=windowext.height,有效繪圖區域為以視口寬高中的最小邊為邊長的正方形區域。比例因子為:

scalex=scaley=min/windowext.width

當對映方式為mm_anisotropic時,有效繪圖區域為整個視口(這裡為客戶區)。比例因子為:

scalex=viewportext.width/windowext.width

scaley=viewportext.height /windowext.height。見圖4.

<4>裝置(視口)座標= (邏輯座標–邏輯視窗原點座標)×比例因子+視口原點座標

圖4 以下分析中客戶區大小為clientrect=(388,200),邏輯視窗原點為windoworg=(100,100)

,基於(3)<4>中修改後的**。

在上圖4左中,nmapmode=mm_isotropic,橢圓外接矩形左上角邏輯座標(-100,300)對映為客戶區的以pixel為單位的座標為:

left_top_x= (-100-100)×(200/1000)+388/2=154 pixel

left_top_y= (300-100)×(200/1000)+200/2=140 pixel

依此次方法可計算出右下角邏輯座標(300,-100)對映為客戶區的以pixel為單位的座標為:

right_bottom_x=234 pixel;right_bottom_y=60 pixel

我們若在第9行dc.setmapmode(mm_isotropic);//x=y

前新增createpen(ps_solid,2,rgb(255,0,0));dc.ellipse(154,140,234,60);則可以發現,這個以2個畫素寬的紅色畫筆繪製的(橢)圓剛好和設定對映模式後繪製的(橢)圓重合。但是我們改變視窗大小時,發現設定對映模式後繪製的(橢)圓按比例拉伸,但紅色圓始終在原地且大小保持不變,這也說明了預設對映方式mm_text是以x軸正方向朝右,y軸正方向朝下的座標系和1 pixel為單位進行繪製的。

同理,我們可以分析上圖4右中,nmapmode=mm_anisotropic的情況下,crect(116,140,272,60);為等效橢圓外接矩形。

MFC GDI座標對映例解

2 找到cmainframe precreatewindow函式,在其中設定預設視窗大小為400 pixel 300 pixel。bool cmainframe precreatewindow createstruct cs 3 新增onpaint事件 資源管理器 classview 右擊cdraw...

紋理對映座標glTexCoordPointer用法

gltexcoordpointer int size,int type,int stride,buffer pointer 設定頂點陣列為紋理座標快取 其中 size 紋理頂點座標的分量個數 size number of coordinates per vertex type 紋理座標的資料型別 s...

座標系統 對映模式

三種座標系統 螢幕座標 全視窗座標 客戶區座標 clienttoscreen 把客戶區座標轉換到螢幕座標 screentoclient 把螢幕座標轉換到客戶區座標 getwindowrect 以螢幕座標形式獲取整個視窗的位置和大小 getclientrect hwnd,rect dptolp hdc...