坐标空间和映射模式
设备坐标空间和映射模式
坐标空间
- 定义: 一个坐标空间是一个平面的空间,通过使用两个相互垂直并且长度相等的轴来定位二维对象
- 分类:
- 世界坐标系空间: 应用程序运用世界坐标系空间对图形输出进行旋转、斜切或者反射
- 页面空间: 称为逻辑空间
- 设备空间: 称为逻辑空间
- 物理设备空间: 通常指应用程序窗口的客户区;但是它也包括整个桌面、完整的窗口(包括框架、标题栏和菜单栏)或打印机的一页或绘图仪的一页纸.物理设备的尺寸随显示器、打印机或绘图仪所设置的尺寸而变化
如下图所示:
开始空间
- 若应用程序调用了SetWorldTransform函数,那么映射就从应用程序的世界坐标系空间开始
- 若应用程序没有调用了SetWorldTransform函数,映射在页面空间中进行
说明
- 如要在物理设备上绘制输出,Windows把一个矩形区域从一个坐标空间拷贝到(或映射到)另一个坐标空间,直至最终完整的输出呈现在物理设备上(通常是屏幕或打印机)
- 在Windows把矩形区域的每一点从一个空间拷贝到另一个空间时,它采用了一种被称作转换的算法,转换是把对象从一个坐标空间拷贝到另一个坐标空间时改变(或转变)这一对象的大小、方位、和形态,尽管转换把对象看成一个整体,但它也作用于对象中的每一点或每条线
不同空间之间的转换
页面空间到设备空间的转换
- 映射方式:
- 页面空间到设备空间的转换是原Windows接口的一部分.这种转换确定与一特定设备描述表相关的所有图形输出的映射方式.所谓映射方式是指确定用于绘图操作的单位大小的一种量度转换.映射方式是一种影响几乎任何客户区绘图的设备环境属性
- 缺省的映射模式为MM_TEXT.在这种映射模式下,逻辑单位和设备单位相同
- 四种设备环境属性:
- 页面空间,采用逻辑单位:
- 窗口原点
- 窗口范围
- 设备空间,采用设备坐标:
- 视口原点
- 视口范围
- 以下四个图片来说明视口与窗口的关系:
图1:
图2:
图3:
图4:
- 页面空间,采用逻辑单位:
- 视口/窗口:
- 改变视口和窗口原点(CDC中提供了两个成员函数函数用来改变视口和窗口的原点)
- SetViewportOrg
- SetWindowOrg,
- 获得视口和窗口原点(CDC中提供了两个成员函数函数用来改变视口和窗口的原点)
- GetViewportOrg
- GetWindowOrg,
- 注意: 不管对窗口和视口原点作什么改变,设备点(0,0)始终是客户区的左上角(即窗口显示的的左上角始终始终为设备点(0,0))
- 说明: 页面空间到设备空间的转换所用的是两个矩形的宽与高的比率,其中页面空间中的矩形被称为窗口,设备空间中的矩形被称为视口,Windows把窗口原点映射到视口原点,把窗口范围映射到视口范围,就完成了这种转换,如上图
- 改变视口和窗口原点(CDC中提供了两个成员函数函数用来改变视口和窗口的原点)
- 逻辑坐标/设备坐标:
- 逻辑坐标:
- “窗口”是基于逻辑坐标的,逻辑坐标可以是象素、毫米、英寸等单位
- 几乎在所有的GDI函数中使用的坐标值都是采用的逻辑单位.Windows必须将逻辑单位转换为“设备单位”,即像素.这种转换是由映射方式、窗口和视口的原点以及窗口和视口的范围所控制的
- 设备坐标:
- “视口”是基于设备坐标(象素)的.通常,视口和客户区是相同的.
- Windows对所有的消息(如WM_SIZE、WM_MOUSEMOVE、WM_LBUTTONDOWN、WM_LBUTTONUP),所有的非GDI函数和一些GDI函数(例如GetDeviceCaps函数),永远使用设备坐标
- 对应关系:
- 如果将视口原点设置为(xViewOrg,yViewOrg),则逻辑点(0,0)就会被映射为设备点(xViewOrg,yViewOrg).如果将窗口原点改变为(xWinOrg,yWinOrg),则逻辑点(xWinOrg,yWinOrg)将会被映射为设备点(0,0),即左上角
- 逻辑坐标和设备坐标的相互转换:
- 非 MM_TEX T映射方式下的逻辑坐标和设备坐标的相互转化
- 窗口(逻辑)坐标转换为视口(设备)坐标的两个公式:
- xViewport=(xWindow-xWinOrg)*xViewExt/xWinExt+xViewOrg
- yViewport=(yWindow-yWinOrg)*xViewExt/xWinEx+yViewOrg
- 视口(设备)坐标转换为窗口(逻辑)坐标的两个公式:
- xWindow=(xViewPort-xViewOrg)*xWinEx/xViewExt+xWinOrg
- yWindow=(yViewPort-yViewOrg)*xWinEx/xViewExt+yWinOrg
- 窗口(逻辑)坐标转换为视口(设备)坐标的两个公式:
- 在 MM_TEXT 映射方式下逻辑坐标和设备坐标的相互转换
- 窗口(逻辑)坐标转换为视口(设备)坐标的两个公式:
- xViewport = xWindow-xWinOrg+xViewOrg
- yViewport = yWindow-yWinOrg+yViewOrg
- 视口(设备)坐标转换为窗口(逻辑)坐标的两个公式:
- xWindow = xViewport-xViewOrg+xWinOrg
- yWindow = yViewport-yViewOrg+yWinOrg
- 窗口(逻辑)坐标转换为视口(设备)坐标的两个公式:
- 非 MM_TEX T映射方式下的逻辑坐标和设备坐标的相互转化
- 逻辑坐标:
设备空间到物理空间的转换
设备空间到物理空间的转换有几个独特之处:它只限于平移,并由Windows的窗口管理部分控制,这种转换的唯一用途是确保设备空间的原点被映射到物理设备上的适当点上.没有函数能设置这种转换,也没有函数可以获取有关数据,程序员无需关心,也无法对这方面做任何操作
默认转换
- 页面空间到设备空间的转换: 默认页面空间到设备空间的转换结果是一对一的映射;即页面空间上给出的一点映射到设备空间的一个点.正如前文讲到的,这种转换没有以矩阵指定,而是通过把视口宽除以窗口宽,把视口高除以窗口高而得出的.在默认的情况下,视口尺寸为1x1个象素,窗口尺寸为1x1页单位
- 设备空间到物理设备: 设备空间到物理设备(客户区、桌面或打印机)的转换结果总是一对一的;即设备空间的一个单位总是与客户区、桌面、或打印机上的一个单位相对应.这一转换的唯一用途是平移.无论窗口移到桌面的什么位置,它永远确保输出能够正确无误地出现在窗口上
- 默认转换的一个独特之处是设备空间和应用程序窗口的y轴方向.在默认的状态下,y轴正向朝下,负y方向朝上
- 一旦应用程序建立了设备描述表,并立即开始调用GDI绘图或输出函数,则运用默认页面空间到设备空间的转换和设备空间到客户区的转换(在应用程序调用SetWorldTransform函数之前,不会出现世界坐标空间到页面空间的转换)
在有滑动条的窗口中图形在绘制图形的时候记得对窗口的视口的对应调整.
比如当窗口下拉时我们在窗口中点击鼠标左键的时候,得到的是设备坐标,但是我们的视口的位置其实是在上面,虽然我们没有改变窗口的视口原点但是为了显示出窗口下部分类容视口原点必须向上移动,因为设备点(0,0)始终是客户区的左上角,所以我们得到的设备坐标坐标值.而并非窗口的视区中对应的位置,也就是说它得到的位置错位了.
所以我们要先用OnPrepareDC函数(OnPrepareDC会随时根据滚动窗口的位置来调整视口的原点),调整了显示上下文的属性,将视口的原点设置为现在对应的位置,并将设备坐标转换为对应的逻辑坐标,使点对应窗口视区对应的位置,可以通过调用完OnPrepareDC函数后调用DptoLP来做对应的设备坐标到逻辑坐标的转换,此后的输出就会正确的显示其位置