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

本文介绍了MFC中逻辑坐标系和设备坐标系的概念及映射模式。设备坐标以像素为单位,逻辑坐标用于记录。默认的MM_TEXT映射模式下,两者方向和单位相同。通过设置视口原点和扩展,可以实现不同形式的坐标系转换,例如创建以客户区中心为原点的坐标系。
摘要由CSDN通过智能技术生成

建立一个合适的坐标系可以为我们的绘图带来很大的方便。下面介绍一下如何在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(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轴向上为正。
运行结果如下图


(菜鸟博客,不喜勿喷~)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值