windows编程之几个坐标,坐标系的概念

来源:互联网 发布:人工智能专家系统实例 编辑:程序博客网 时间:2024/06/06 10:39
利用GDI绘图的时候需要明白几个概念 设备坐标与逻辑坐标的区别,viewPort跟windowsPort的区别
<1>设备坐标跟逻辑坐标
设备坐标包括三种,客户区坐标,窗口坐标,屏幕坐标,它的特点是以左上角为原点,x轴向右递增,y轴向下递增,单位是像素。
逻辑坐标默认情况下跟设备坐标重合,采用像素为单位,但是逻辑坐标的单位并不一定是像素,它可以是具体的物理度量单位,包括mm,inch。我们再绘图的时候采用的都是逻辑单位,windows会把这些逻辑单位转换为像素单位。


<2>viewPort 和 windowsPort
这两者的翻译是视口,窗口。视口是基于设备坐标(像素的),窗口是基于逻辑坐标的,默认情况下两者重合。但是可以设置视口坐标系的原点以及窗口坐标系的原点。这时候要理解两个函数 SetViewportOrg(x,y),SetWindowportOrg(x,y)。
SetViewportOrg(x,y):指定设备点(x,y)映射到逻辑点(0,0);//视口原点跟窗口原点匹配
SetWindowPortOrg(x,y):指定逻辑点(x,y)映射到设备点(0,0)//


注意点:
要注意区分视口坐标系原点跟视口原点的区别,窗口坐标系原点跟窗口原点的区别。
视口坐标系其实就是设备坐标系,它是固定不变的,因此设备原点永远是(0,0)。
视口原点是可变的,它默认处于设备原点,但是可以更改。
窗口坐标系指定了在窗口绘图时的参考点,参考点就是窗口坐标系的原点。
窗口原点默认等于窗口坐标系原点,但是窗口原点可以改变。
窗口原点永远跟视口原点匹配映射。//这个是最主要的


根据公式:
xViewport = (xWindow - xWinOrg)× xViewExt /xWinExt + xViewOrg;
yViewport = (yWindow - yWinOrg)× yViewExt /yWinExt + yViewOrg;


从这个公式可以看到 逻辑点 (xWinOrg,yWinOrg)映射到 (xViewOrg,yViewOrg)从而证明了窗口原点永远跟视口原点匹配映射。

示例代码:

#include <Windows.h>#include<stdio.h>#pragma comment(lib, "winmm.lib")LRESULT CALLBACK WndProc( HWND hwnd,      // handle to window UINT uMsg,      // message identifier WPARAM wParam,  // first message parameter LPARAM lParam   // second message parameter );int WINAPI WinMain(HINSTANCE hInstance,      // handle to current instanceHINSTANCE hPrevInstance,  // handle to previous instanceLPSTR lpCmdLine,          // command lineint nCmdShow              // show state ){static TCHAR szAppName[]=TEXT("HelloWin");HWND hwnd;MSG msg; WNDCLASS wndcls; wndcls.cbClsExtra=0; wndcls.cbWndExtra=0; wndcls.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); wndcls.hCursor=LoadCursor(NULL,IDC_ARROW); wndcls.hIcon=LoadIcon(NULL,IDI_APPLICATION); wndcls.hInstance=hInstance; wndcls.lpfnWndProc=WndProc; wndcls.lpszClassName=szAppName; wndcls.lpszMenuName=NULL; wndcls.style=CS_HREDRAW | CS_VREDRAW; if(!RegisterClass(&wndcls)) {MessageBox(NULL,TEXT("error"),szAppName,MB_OKCANCEL);return 0; }hwnd=CreateWindow(szAppName,TEXT("the hello program!"),WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);ShowWindow(hwnd,SW_SHOWNORMAL);UpdateWindow(hwnd); while(GetMessage(&msg,NULL,0,0)) {  TranslateMessage(&msg);  DispatchMessage(&msg); } return 0;}LRESULT CALLBACK WndProc( HWND hwnd,      // handle to window UINT uMsg,      // message identifier WPARAM wParam,  // first message parameter LPARAM lParam   // second message parameter ){ HDC hdc; PAINTSTRUCT ps; RECT rect; POINT pt1,pt2; switch(uMsg) { case WM_PAINT:hdc = GetDC(hwnd);GetClientRect(hwnd,&rect);SetViewportOrgEx(hdc,rect.right/2,rect.bottom/2,NULL);SetWindowOrgEx(hdc,-rect.right/2,-rect.bottom/2,NULL);Rectangle(hdc,0,0,-100,-100);GetViewportOrgEx(hdc,&pt1);GetWindowOrgEx(hdc,&pt2);ReleaseDC(hwnd,hdc);return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd,uMsg,wParam,lParam);}
可以调试程序观测程序运行时候点pt1,pt2对应的值。通过对比就很容易发现问题,拨开迷雾见晴天。

0 0
原创粉丝点击