理解windows的移动原点
估计很多人看了Jeff Prosise《MFC Windows程序设计》或 Charles Petzold《Programming Windows》,对于移动原点的描述会有点不好理解。以下是个人的整理,希望大家看了,能明白是怎么回事。
造成不好理解的原因,我想是源自SetWindowOrg和SetViewportOrg的函数描述,
SetWindowOrg: 移动窗口的原点
SetViewportOrg: 移动视口的原点
其实,用“窗口”和“视口”这两个名词,在这里用来理解移动原点的概念,会造成初学者理解上的混淆(Programming Windows》里也有提及)。对于大多数初学者来说对于窗口的理解就是我们在屏幕上所看到窗口,而SetWindowOrg 所说的窗口,其实跟我们平常所说窗口是两回事。还有不是有了窗口了吗,怎么还有一个视口呢?
要解开这些疑惑,那么我们首先要摒弃窗口在我们原来脑海中的概念,然后理解坐标系统。一定要切记Windows操作系统有两套坐标系,一个是逻辑坐标,另一个是设备坐标。怎么理解这两个坐标系统?
逻辑坐标,就理解成在某几何作业本上画的直角坐标系,坐标值可以是无限的,Windows的绘图基本上是以逻辑坐标作为参数的,也就是说Windows绘图是在逻辑平面上进行的。
设备坐标,是物理的,就理解成你手上拿着一个方形的框框(如显示器),通过该方框可以看到逻辑坐标画的东西,设备坐标左上角的坐标永远是(0,0)。设备总是有尺寸的,只能显示某个范围的内容。
默认情况,两个坐标系都是Y轴向下递增,X轴向右递增的,由于两者的原点是重合的,因此给了初学者的感觉Window只有1个坐标系,如图1。
红色方框内,就是我们在设备能看到的内容,默认情况下,逻辑坐标系里-x,-y 的内容在设备上是看不到,图2显示了以下代码的效果
CRect rect(-100,-100,100,100);
dc.Rectangle(rect) ;
dc.Ellipse(rect) ;
那么我们怎么才能显示出(-x,-y)的内容呢,使用移动原点是其中一种方法。以下2个函数重新进行了说明,更容易大家理解。
SetWindowOrg: 移动逻辑坐标的原点,即通知操作系统,把逻辑点(x,y)映射成设备点(0,0),
SetViewportOrg: 移动设备坐标的原点,即通知操作系统把 设备点(x,y)映射成逻辑点(0,0),更通俗的讲 显示设备(x,y)点显示的是 逻辑坐标点(0,0)的内容。
两个的函数所要实现的功能是一样的(注意x,y参数的正负),个人觉得SetViewportOrg 相对好理解一下。
用其中一个函数设定原点后,操作系统在绘图时会自动进行坐标转换,显示出需要的内容。
以下代码演示了居中显示,(-x,-y)的内容可以看到了,其2个坐标系也画了出来,如图3
CPaintDC dc(this);
CRect rect;
GetClientRect(&rect); //返回以设备单位表示的窗口尺寸(即像素)
CPoint point(rect.Width()/2,rect.Height()/2);
dc.SetViewportOrg(point);
CRect rect2(-100,-100,100,100);
dc.Rectangle(rect2) ;
dc.Ellipse(rect2) ;
记住:设备坐标的左上角永远是(0,0)见上图红色标识的O‘,我们在屏幕上看到的实际是设备坐标与逻辑坐标映射后的结果。
参考:
《MFC Windows程序设计》
《Programming Windows》
http://blog.csdn.net/benny5609/archive/2007/10/26/1845645.aspx