分类: C/C++
2008-04-23 21:57:12
World space 到 Page space 的转换简介
作者:
一、坐标空间和 World space 到 Page space的转换
坐标空间是一个平面的,在上面图形都是以平面直角坐标定位的。应用程序借助坐标空间可以缩放,平移,剪切,镜像图形的输出。
在Windows GDI中涉及到以下几种坐标空间
世界坐标空间(world space) 页面坐标空间(page space) 设备坐标空间(device space) 物理坐标空间(physical device space)通过转换可以改变目标的大小,方向,形状,转换同时能把图形目标从一个坐标空间转化 到另一个坐标空间,最终在物理设备如屏幕、打印机上显示出来。
typedef struct _XFORM { FLOAT eM11; FLOAT eM12; FLOAT eM21; FLOAT eM22; FLOAT eDx; FLOAT eDy; }XFORM, *PXFORM;用于变换的矩阵数据。
int SetGraphicsMode( HDC hdc, // handle to device context int iMode // graphics mode );设定设备环境上下文(DC)的graphics mode , 当graphics mode设定为GM_ADVANCED才能 支持世界变换。
BOOL SetWorldTransform( HDC hdc, // handle to device context CONST XFORM *lpXform // transformation data );设定设备环境上下文(DC)的世界变换。
BOOL CombineTransform( LPXFORM lpxformResult, // combined transformation CONST XFORM *lpxform1, // first transformation CONST XFORM *lpxform2 // second transformation );世界变换的组合运算。
BOOL GetWorldTransform( HDC hdc, // handle to device context LPXFORM lpXform // transformation );得到设备环境上下文(DC)的世界变换。
FLOAT eM11; FLOAT eM12; FLOAT eM21; FLOAT eM22; FLOAT eDx; FLOAT eDy;则变换计算公式如下:
| eM11 eM12 0 | |x'' y'' 1| = |x y 1| * | eM21 eM22 0 | | eDx eDy 1 |三、示例 将图形以原点为中心逆时针旋转。
01void TransformAndDraw(int iTransform,HWND hWnd)? 02{ 03 HDC hDC; 04 XFORM xForm; 05 RECT rect; 06 ::GetClientRect(hWnd, (LPRECT) &rect); 07 hDC = ::GetDC(hWnd); 08 ::MoveToEx(hDC ,rect.right / 2 , 0 , NULL ) ; 09 ::LineTo(hDC , rect.right / 2 , rect.bottom ) ; 10 ::MoveToEx(hDC , 0 , rect.bottom / 2 , NULL ) ; 11 ::LineTo(hDC , rect.right , rect.bottom / 2) ; 12 ::SetGraphicsMode(hDC, GM_ADVANCED); 13 switch (iTransform) 14 { 15 case 0: 16 AfxGetMainWnd()->SetWindowText("原始图像") ; 17 break; 18 case 1: // Scale to 1/2 of the original size. 19 xForm.eM11 = (FLOAT) 0.5; 20 xForm.eM12 = (FLOAT) 0.0; 21 xForm.eM21 = (FLOAT) 0.0; 22 xForm.eM22 = (FLOAT) 0.5; 23 xForm.eDx = (FLOAT) 0.0; 24 xForm.eDy = (FLOAT) 0.0; 25 ::SetWorldTransform(hDC, &xForm); 26 AfxGetMainWnd()->SetWindowText("缩小到一半") ; 27 break; 28 29 case 2: // Translate right by 3/4 inch. 30 xForm.eM11 = (FLOAT) 1.0; 31 xForm.eM12 = (FLOAT) 0.0; 32 xForm.eM21 = (FLOAT) 0.0; 33 xForm.eM22 = (FLOAT) 1.0; 34 xForm.eDx = (FLOAT) 75.0; 35 xForm.eDy = (FLOAT) 0.0; 36 ::SetWorldTransform(hDC, &xForm); 37 AfxGetMainWnd()->SetWindowText("平移") ; 38 break; 39 40 case 3: // Rotate 30 degrees counterclockwise. 41 xForm.eM11 = (FLOAT) 0.8660; 42 xForm.eM12 = (FLOAT) 0.5000; 43 xForm.eM21 = (FLOAT) -0.5000; 44 xForm.eM22 = (FLOAT) 0.8660; 45 xForm.eDx = (FLOAT) 0.0; 46 xForm.eDy = (FLOAT) 0.0; 47 ::SetWorldTransform(hDC, &xForm); 48 AfxGetMainWnd()->SetWindowText("旋转") ; 49 break; 50 51 case 4: // Shear along the x-axis with a 52 // proportionality constant of 1.0. 53 xForm.eM11 = (FLOAT) 1.0; 54 xForm.eM12 = (FLOAT) 1.0; 55 xForm.eM21 = (FLOAT) 0.0; 56 xForm.eM22 = (FLOAT) 1.0; 57 xForm.eDx = (FLOAT) 0.0; 58 xForm.eDy = (FLOAT) 0.0; 59 ::SetWorldTransform(hDC, &xForm); 60 AfxGetMainWnd()->SetWindowText("剪切") ; 61 break; 62 63 case 5: // Reflect about a horizontal axis. 64 xForm.eM11 = (FLOAT) 1.0; 65 xForm.eM12 = (FLOAT) 0.0; 66 xForm.eM21 = (FLOAT) 0.0; 67 xForm.eM22 = (FLOAT) -1.0; 68 xForm.eDx = (FLOAT) 0.0; 69 xForm.eDy = (FLOAT) 0.0; 70 ::SetWorldTransform(hDC, &xForm); 71 AfxGetMainWnd()->SetWindowText("水平镜像") ; 72 break; 73 74 case 6: // Reflect about a Vertical axis. 75 xForm.eM11 = (FLOAT) -1.0; 76 xForm.eM12 = (FLOAT) 0.0; 77 xForm.eM21 = (FLOAT) 0.0; 78 xForm.eM22 = (FLOAT) 1.0; 79 xForm.eDx = (FLOAT) 0.0; 80 xForm.eDy = (FLOAT) 0.0; 81 ::SetWorldTransform(hDC, &xForm); 82 AfxGetMainWnd()->SetWindowText("垂直镜像") ; 83 break; 84 85 } 86 ::DtoLP(hDC, (LPPOINT) &rect, 2); 87 HBITMAP hBMP1; 88 hBMP1 = ::LoadBitmap(AfxGetResourceHandle() , MAKEINTRESOURCE(IDB_BITMAP1)) ; 89 HDC hImageDC = ::CreateCompatibleDC((HDC)hDC); 90 HBITMAP hOldImageBMP = (HBITMAP)::SelectObject( hImageDC , hBMP1 ); 91 ::BitBlt((HDC)hDC,(rect.right/2 -40),(rect.bottom / 2 -40), 80,80,hImageDC,0,0,SRCCOPY ); 92 ::SelectObject((HDC)hDC , hOldImageBMP); 93 ::DeleteObject(hBMP1) ; 94 ::DeleteDC(hImageDC) ; 95 ::ReleaseDC(hWnd, hDC); 96 }四、结束语