zoukankan      html  css  js  c++  java
  • 【转载】GDI 映像方式 之 SetViewportOrgEx 与 SetWindowOrgEx 解析

    SetViewportOrgEx 与 SetWindowOrgEx 解析

         这两个函数,用来改变视端口和窗口的原点,并都具有改变轴的效果,以致(0,0)不再指左上角。

        「视端口」是依据设备坐标(图素)的。通常,视端口和显示区域相同.视端口也可以是指整窗口坐标或者屏幕坐标。点(0,0)是显示区域(或者整个窗口或屏幕)的左上角,x的值向右增加,y的值向下增加。

       「窗口」是依据逻辑坐标的,逻辑坐标可以是图素、毫米、英寸或者您想要的任何其它单位。

        对于视端口和窗口的概念可以这样理解: 幻想显示器大小可以随便改变,那么显示器每次都变成view「视端口」的太小就可以了,window「窗口」就没存在的必要了。

    view「视端口」就是实际所需的大小; window「窗口」就是显示器给你的限制。

    再来看下Windows中的几种坐标体系

    1、屏幕坐标 
    屏幕坐标描述物理设备(显示器、打印机等)的一种坐标体系,坐标原点在屏幕的左上角,X轴向右为正,Y轴向下为正。度量单位是图素。原点、坐标轴方向、度量单位都是不能够改变的。
      2、设备坐标(又称物理坐标)  
    设备坐标是描述在屏幕和打印机显示或打印的窗体的一种坐标体系。坐标原点是在其客户区的左上角。X轴向右为正,Y轴向下为正。度量单位为图素。原点和坐标轴方向可以改变,但是度量单位不可以改变。  
    3、逻辑坐标  
    逻辑坐标是在程序中控制显示,打印使用的坐标体系。该坐标系与定义的映射模式密切相关。默认的映射模式是MM_TEXT。我们可以通过设置不同的映射模式来改变该坐标体系的默认行为。 我们使用逻辑坐标系绘图,然后要在设备坐标系下显示。所以就有一个逻辑坐标和设备坐标之间的转换。

    SetViewportOrgEx的参数总是使用设备坐标系单位(图素)。 假设显示区域为cxClient个图素宽和cyClient个图素高。映像方式为MM_TEXT。 如果想将逻辑点(0,0)定义为显示区域的中心,可进行如下呼叫:

    SetViewportOrgEx (hdc, cxClient / 2, cyClient / 2, NULL) ;  逻辑点(0,0)将映像为设备点(cxClient/2,cyClient/2)。

    显示区域的坐标系变成如下形状:

    xy1

    SetWindowOrgEx的参数总是使用逻辑单位。 要想获得与上面使用SetViewportOrgEx同样的效果则可以进行如下呼叫:

    SetWindowOrgEx (hdc, -cxClient / 2, -cyClient / 2, NULL) ; 逻辑点(-cxClient  / 2,-cyClient / 2)映像为设备点(0,0),即显示区域的左上角。


    很多人对于SetWindowOrgEx使用负数坐标参数表示很困惑,当然也包括我自己。进过几天的思考,终于恍然大悟。这里做一下解释。

    首先要知道 不管对窗口和视端口原点作什么改变,设备坐标点(0,0)始终是显示区域的左上角。

    我是这样理解的,窗口(逻辑)原点始终指向视端口(设备)原点。这样就很好解释了。

    SetViewportOrgEx (hdc, cxClient / 2, cyClient / 2, NULL) ;  逻辑点(0,0)将映像为设备点(cxClient/2,cyClient/2)。

    设置视端口中心点为设备原点,逻辑原点映射之。

    SetWindowOrgEx (hdc, -cxClient / 2, -cyClient / 2, NULL) ; 逻辑点(-cxClient  / 2,-cyClient / 2)映像为设备点(0,0),即显示区域的左上角。

    将逻辑原点起始坐标设置为 (-cxClient  / 2,-cyClient / 2),再映射到设备原点。

    假设函数调用时坐标如图所示:

         xy2

    首先,将坐标(-50 , -50)设置为逻辑原点的起始坐标。

    然后,将逻辑原点映射到设备原点,这里是显示区域的左上角。

    函数调用后上图改变为:

    xy3

    当我们使用逻辑坐标-50,-50的时候,被映像到了设备原点,也就是显示区域的左上角。

    当我们使用逻辑坐标0,0的时候,便被映像到了设备中心点。

    我们绘图的时候使用的是逻辑坐标,系统显示图像的时候是使用设备坐标,所以会有一个转换过程。

    现在我们在逻辑坐标50,50处进行绘图,映像方式为MM_TEXT(转换比率1:1),系统显示时转换为设备坐标:

    设备坐标点X = (50 - (-50 ) ) * (1/1) + 0 = 100

    设备坐标点Y = (50 - (-50 ) ) * (1/1) + 0 = 100

    这下清楚了吧。


    再附下设备坐标与逻辑坐标的转换公式:

    设备坐标点X = (待转换的逻辑点X - 逻辑坐标的窗口原点X) * (设备坐标的视端口范围X / 逻辑坐标的窗口范围X) + 设备坐标的视端口原点X

    逻辑坐标点X = (待转换的设备点x - 设备坐标的视端口原点x) * (逻辑坐标的窗口范围x / 设备坐标的视端口范围x) + 逻辑坐标的窗口原点x

    原文地址:http://blog.csdn.net/typecool/article/details/5898110

    重剑无锋,大巧不工
  • 相关阅读:
    C Python类型互换
    C、C++中如何成功嵌入python
    常见Style 对象属性值
    转: , , 的区别
    dom4j: 用dom4j生成xml后第二行空行的问题
    dom4j: 生成的XML文件根节点 xmlns="" 的问题
    android
    android studio
    android studio
    FFmpeg编译: undefined reference to 'av_frame_alloc()'
  • 原文地址:https://www.cnblogs.com/919czzl/p/4075326.html
Copyright © 2011-2022 走看看