您的位置:首页 > 其它

[MFC]逻辑坐标系和设备坐标系

2017-12-03 00:47 197 查看
建立一个合适的坐标系可以为我们的绘图带来很大的方便。下面介绍一下如何在VC中建立我们想要的坐标系。

(1)
设备坐标(Device Coordinate)又称为物理坐标(Physical Coordinate)。设备坐标用对象距离客户区窗口左上角的水平距离和垂直距离来指定对象的位置,是以像素为单位来表示的。
逻辑坐标(LogicalCoordinate)是系统用作记录的坐标。

(2)
映射模式被定义为从窗口(window也即逻辑坐标)到视口(viewport也即设备坐标)的映射。(从逻辑坐标系到设备坐标系的映射,目的是产生逻辑坐标系)
(3)
在windows中选择设备坐标点(0,0)为参考点,设备坐标点(0,0)始终都位于客户区的左上角。

(4)
设备坐标系的X轴向右为正,Y轴向下为正,坐标原点位于客户区窗口的左上角,且固定不变(看(3))。

在默认情况下的,vs采用的是MM_TEXT映射模式,该模式下,逻辑坐标系的方向和单位与设备坐标系的方向和单位相同,也是以像素为单位来表示的,X轴向右为正,Y轴向下为正,坐标原点位于客户区窗口的左上角。

默认情况下,逻辑坐标系采用MM_TEXT映射模式,该映射模式下逻辑坐标系的方向与设备坐标系的方向相同:X轴的正方向向右,Y轴的正方向向下。再加上坐标原点重合,故给人的感觉是只有一个坐标系,具体如图1所示:(视口就是蓝色框,采用不同的模式可以让蓝色框移动)



直接进入实例来理解坐标系
1、建立以左上角为原点,X轴和Y轴为1000的坐标系,如下图



void CzbView::OnDraw(CDC* pDC)
{
CzbDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;

// TODO: 在此处为本机数据添加绘制代码
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). GetClientRect(&rect); 取得客户区矩形区域,将其存放在rect中。

2). 用pDC->SetMapMode(MM_ANISOTROPIC); 设置映射模式。

3). 通过pDC->SetViewportOrg(0,0)与pDC->SetWindowOrg(0,0)设置设备坐标系(视口)的原点与逻辑坐标系(窗口)的原点。(即视口、窗口)(记住:设备坐标系左上角固定为(0,0))

4). 通过pDC->SetViewportExt(rect.right,rect.bottom)和pDC->SetWindowExt(1000,1000)来确定逻辑坐标系和设备坐标系的尺寸对应关系。(这2行代码的意思是把设备坐标系的右下角那个点看作是逻辑坐标系的(1000,1000))

5). 在MM_ANISOTROPIC模式下,X轴单位和Y轴单位可以不相同。

6). 通过第四步的解释,可以知道逻辑坐标系的方向和设备坐标系的方向相同,即X轴向右为正,Y轴向下为正。

运行结果下图



2、实现我们熟悉的坐标系,以客户区的中心为(0,0)点(这个点是逻辑原点),画一个三角形,此时x轴往右增大,y轴往上增大

void CzbView::OnDraw(CDC* pDC)
{
CzbDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;

// TODO: 在此处为本机数据添加绘制代码
CRect rect;
GetClientRect(&rect);

pDC->MoveTo(rect.Width()/2,0);//画坐标系用的
pDC->LineTo(rect.Width()/2,rect.Height());//画坐标系用的
pDC->MoveTo(0,rect.Height()/2);//画坐标系用的
pDC->LineTo(rect.Width(),rect.Height()/2);//画坐标系用的

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(
9709
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)来确定设备坐标系和逻辑坐标系的对应关系。(这2行代码的意思是把设备坐标系的右下角那个点看作是逻辑坐标系的(1000,-1000),其实这就说明了从视口原点开始向下为负,向上为正)

3). 因为逻辑坐标系(x轴往右增大,y轴往上增大)和设备坐标系(x轴往右增大,y轴往下增大)的不一致,即纵坐标取反了,所以逻辑坐标系的Y轴向上为正。

运行结果如下图



(菜鸟博客,不喜勿喷~)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: