MFC 逻辑坐标原点与设备坐标原点的移动

转自http://blog.sina.com.cn/s/blog_6ab0b9a80101dwud.html

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------

参考:http://blog.csdn.net/benny5609/archive/2007/10/26/1845645.aspx

http://www.cnblogs.com/finema/archive/2011/05/30/2059067.html
http://baike.baidu.com/view/4059670.htm
这几个网站上讲的不太全面,自己正在总结,先占个坑

自己总结,不对的地方望大家指正:
《MFC Windows 程序设计》P41中讲解的关于SetWindowOrg和SetViewportOrg的使用,这里先呈上自己摘自网络和课本的一些知识:
①原点概念的理解:在数学中常称点(0,0)为坐标原点,但是在windows中原点是一个坐标,但并未必是(0,0)点。原点这个说法的使用时为了联系设备坐标和逻辑坐标---设备坐标的原点一定要和逻辑坐标的原点重合。
②映射模式被定义为从窗口(window也即逻辑坐标)到视口(viewport也即设备坐标)的映射,具体的内容可以参考: 《MFC Windows 程序设计》 P36和《Windows程序设计》P147。
③既然用坐标来标注设备坐标系和逻辑坐标系的原点,那么二者坐标值的求取必须具有同一个参考对象,也就是说必须有一个参考点来确定设备坐标中原点和逻辑坐标中的原点的坐标。在windows中选择设备坐标点(0,0)为参考点,设备坐标点(0,0)始终都位于客户区的左上角。( 《Windows程序设计》 P147
④传送给CDC输出函数的是逻辑坐标, 《MFC Windows 程序设计》 P36
逻辑坐标:可理解成几何作业本上的直角坐标系,坐标值是无限的,Windows的绘图是以逻辑坐标作为参数,也就是说Windows绘图是在逻辑平面上进行的。
设备坐标:是物理的,就理解成手上拿着的方形框框(如显示器),通过该方框可以看到在逻辑平面上所画的东西。设备坐标的左上角永远是(0,0)点,且X轴的正方向向右,Y轴的正方向向下。设备总是有尺寸的,只能显示某个范围的内容。
默认情况下,逻辑坐标采用MM_TEXT映射模式,该映射模式下逻辑坐标的方向与设备坐标系的方向相同: X轴的正方向向右,Y轴的正方向向下。再加上坐标原点重合,故给人的感觉是只有一个坐标系,具体如图1所示:

MFC <wbr>逻辑坐标原点与设备坐标原点的移动

图1

⑥举例说明SetWindowOrg和SetViewportOrg的使用

在默认的情况下逻辑坐标到设备坐标的映射模式为:MM_TEXT,为方便起见这里不再更改映射模式,在默认的情况下:窗口原点为(0,0)点,视口原点也为(0,0)点。

假设将设备原点移到窗口的中心点,即现有的视口原点不再是(0,0)而是窗口中心点。

设dc为一个设备描述表对象,具体实现如下:

CRect rect;
GetClientRect (&rect);//返回的是设备坐标,而SetViewportOrg需要的也是设备坐标,故此处不用转换
dc.SetViewportOrg (rect.Width ()/2, rect.Height ()/2);

图解分析如图2所示

MFC <wbr>逻辑坐标原点与设备坐标原点的移动

图2

具体分析:Ⅰ:将视口原点由(0,0)点移至(x,y)等价于把逻辑点(0,0)映射成设备点(x,y)。
Ⅱ:设备坐标原点与逻辑坐标原点必须重合。
Ⅲ:默认情况下逻辑坐标的原点为(0,0)点,且本处只移动了设备坐标原点,并没有移动逻辑坐标原点,故逻辑坐标的原点仍为(0,0)点,不过要满足Ⅱ中的条件,逻辑坐标系发生了移动,移动结果如图2所示,此时移动后的设备原点(rect.Width ()/2, rect.Height ()/2)与逻辑原点(0,0)重合。
⑦在上面的⑥中将视口原点移到视口的中点,并完成了将逻辑原点到视口中点的映射。为达到相同的效果,用
SetWindowOrg移动逻辑坐标原点也可以达到相同的效果。
为使理解更加清晰透彻,这里做了两组对比的实验
实验一
CRect rect;
GetClientRect (&rect);
CPoint point (rect.Width () / 2, rect.Height () / 2);
dc.DPtoLP (&point);
dc.SetWindowOrg (point.x, point.y);
该实验的逻辑坐标原点移动的示意图如图3所示:

MFC <wbr>逻辑坐标原点与设备坐标原点的移动

图3

在图3中若进行正常移动则逻辑原点将移至设备坐标系的中点,为保证逻辑原点与设备原点的重合,必须移动设备原点(注:由于设备原点没有移动,仍是(0,0)点),但是根据规定设备坐标点是不能移动的,由前面的③可知,作为参考点的设备点(0,0)是不能移动的,不过此处设备点(0,0)恰好又是设备原点而已,故不能移动。既然设备原点不能移动,却又要满足逻辑坐标原点(point.x, point.y)与设备坐标原点(0,0)的重合,只能进行等价移动逻辑坐标系,移动如图3所示:很明显逻辑坐标原点为(point.x, point.y)且满足改点与
设备坐标原点(0,0)的重合。不过对比图2,很明显通过对设备坐标原点进行该种移动不能达到相同的效果,即实验一并未得到与⑥中同样的结果。

实验二
CRect rect;
GetClientRect (&rect);
CPoint point (rect.Width () / 2, rect.Height () / 2);
dc.DPtoLP (&point);
dc.SetWindowOrg (-point.x, -point.y);
该实验的逻辑坐标原点移动的示意图如图4所示:

MFC <wbr>逻辑坐标原点与设备坐标原点的移动

图4

具体的分析与实验一类似,这里不再赘述了,与图2对比很明显得到:对逻辑坐标原点进行这种移动可达到与移动设备坐标原点相同的效果,但有一点值得注意:达到的效果相同,但进行这种移动后设备坐标原点为(0,0),逻辑坐标原点为(-point.x, -point.y),而在图2中经过移动设备坐标原点后:设备原点为(rect.Width ()/2, rect.Height ()/2),逻辑原点为(0,0)。
总结:关于其余映射模式下的移动以及同时采用逻辑坐标原点和谁被坐标原点移动的情况同样可采用上面的分析方法,不过特别注意不同映射模式下的原点移动
P.S.本文是作者本文根据网站参考资料和书籍进行的总结,有不对之处望大家指正,在此也谢过网友博文的指点。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值