建立一個合適的座標系可以為我們的繪圖帶來很大的方便。下面介紹一下如何在VC中建立我們想要的座標系。
一 裝置座標和邏輯座標
裝置座標(Device Coordinate)又稱為物理座標(Physical Coordinate),是指輸出裝置上的座標。通常將螢幕上的裝置座標稱為螢幕座標。裝置座標用對象距離視窗左上方的水平距離和垂直距離來指定對象的位置,是以像素為單位來表示的,裝置座標的X軸向右為正,Y軸向下為正,座標原點位於視窗的左上方。
邏輯座標(Logical Coordinate)是系統用作記錄的座標。在預設的模式(MM_TEXT)下,邏輯座標的方向和單位與裝置座標的方向和單位相同,也是以像素為單位來表示的,X軸向右為正,Y軸向下為正,座標原點位於視窗的左上方。邏輯座標和裝置座標即使在預設模式下其數值也未必一致,除了在以下兩種情況下:
1. 視窗為非滾動視窗
2. 視窗為滾動視窗,但垂直捲軸位於滾動邊框的最上端,水平捲軸位於最左端,但如果移動了捲軸這兩種座標就不一致了。
在VC中滑鼠座標的座標位置用裝置座標表示,但所有GDI繪圖都用邏輯座標表示,所以用滑鼠繪圖時,那麼必須將裝置座標轉換為邏輯座標,可以使用CDC 函數DptoLP()將裝置座標轉化為邏輯座標,同樣可以用LptoDP()將邏輯座標轉化為裝置座標。
二 座標模式
為了在不同的領域使用邏輯座標,Windows提供了以下8種座標模式:
分別為MM_TEXT、MM_HIENGLISH、MM_LOENGLISH、MM_HIMETRIC、MM_LOMETRIC、MM_TWIPS、MM_ANISOTROPIC和MM_ISOTROPIC。
三 執行個體解析
(一) 建立以左上方為原點,X軸和Y軸為1000的座標,如
我們可以用以下代碼:
void CTtView::OnDraw(CDC* pDC) { CTtDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); CRect rect; GetClientRect(&rect); pDC->SetMapMode(MM_ANISOTROPIC); pDC->SetViewportOrg(0,0); pDC->SetViewportExt(rect.right,rect.bottom); pDC->SetWindowOrg(0,0); pDC->SetWindowExt(1000,1000); pDC->MoveTo(50,50); pDC->LineTo(50,950); pDC->LineTo(950,950); pDC->LineTo(50,50); }
程式碼分析:
1. GetClientRect(&rect); 取得客戶區矩形地區,將其存放在rect中
2. 用pDC->SetMapMode(MM_ANISOTROPIC); 設定映射模式
3. 通過pDC->SetViewportOrg(0,0);設定邏輯座標的原點
4. 通過pDC->SetViewportExt(rect.right,rect.bottom);和
pDC->SetWindowExt(1000,1000);來確定邏輯座標下和裝置座標下的尺寸對應關係
5. 在MM_ANISOTROPIC模式下,X軸單位和Y軸單位可以不相同
6. 座標方向的確定方法是如果邏輯窗範圍和視口範圍符號相同,則邏輯座標的方向和視口的方向相同,即X軸向右為正,Y軸向下為正。
7. 如果將顯示模式改為MM_ISOTROPIC,那麼X軸單位和Y軸單位一定相同,感興趣的讀者可以自己使一下。
(二) 建立以視窗中心為原點的座標,如
用如下代碼:
void CTtView::OnDraw(CDC* pDC) { CTtDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); CRect rect; GetClientRect(&rect); pDC->SetMapMode(MM_ANISOTROPIC); pDC->SetViewportOrg(rect.right/2,rect.bottom/2); pDC->SetViewportExt(rect.right,rect.bottom); pDC->SetWindowOrg(0,0); pDC->SetWindowExt(1000,-1000); pDC->MoveTo(150,150); pDC->LineTo(-150,-200); pDC->LineTo(150,-150); pDC->LineTo(150,150); }
程式碼分析:
1. 用 pDC->SetViewportOrg(rect.right/2,rect.bottom/2); 設定視口的原點。
2. 用pDC->SetViewportExt(rect.right,rect.bottom);和pDC->SetWindowExt(1000,-1000);來確定裝置座標和邏輯座標的單位對應關係。
3. 因為邏輯窗範圍和視口範圍的符號不一致,縱座標取反,所以Y軸向上為正。