按习惯,(0,0)就原点,原点就是(0,0),但是如果用此来理解windows的map mode,就会走弯路。其实,稍微改变一下观念,windows的map mode就比较好理解了。举例说明:page space---->device spacepDC->SetMapMode(MM_LOMETRIC);pDC->SetWindowOrg(40,0); //这句“设定”page space的原点为(40,0),注意,//这时(40,0)就是原点,原点就是(40,0)这个点,其实,(0,0)与原点没有必然联系。这//一句对下面的画图函数在page space中所作的图不会有任何影响。一句话:SetWindowOrg //就是指定一下,page space中哪个点为原点。pDC->Rectangle(0,0,100,-100);pDC->Rectangle(0,-100,50,-200);同理,SetViewportOrg也是指定一下,device space中哪个点为原点,两个坐标系映射时,两个原点重合。SetWindowExt设定page space的大小,SetViewportOrg设定device space的大小,其实,真正有意义的只是两者的比例关系,例如,在一个1024*768的显示屏上:pDC->SetMapMode(MM_ISOTROPIC);pDC->SetWindowExt(10240,7680);pDC->SetViewportExt(1024,768);pDC->Rectangle(0,0,100,100); 就会画一个10 pixels*10 pixels的矩形。其本质就是,X方向,每个逻辑单位有1024/10240个象素,Y方向每个逻辑单位有768/7680个象素。因此,下面的代码有相同的作用:pDC->SetMapMode(MM_ISOTROPIC);pDC->SetWindowExt(102400,76800);pDC->SetViewportExt(10240,7680);pDC->Rectangle(0,0,100,100);两者本质一样,前者更易于理解 
 
 
最近突然又很有激情的开始看Jeff Prosise的那本"Programming Windows with MFC, 2 ed."。尽管是英文版的,但是感觉这本书上手比喉结的那本所谓的 深入浅出MFC 要容易理解的多。候同学给人一种故弄玄虚故作深沉的感觉,而Jeff Prosise的这本书才真正的称得上是深入浅出。
尽管如此,其中有关GDI绘图中的坐标映射部分还是有一个问题没有搞清楚,那就是SetWindowOrg和SetViewportOrg这两个函数到底应该如何理解。潘爱民翻译的那本VC内幕没有讲清楚;Jeff Prosise的这本书没有讲清楚;MSDN上的东西看的也是一头雾水;Charles Petzold的那本书还没有来得及看。因为这个问题,昨天晚上是带着遗憾的困惑入睡的。
总的来说,我对这两个函数的理解导致的结果是与实际程序运行的结果截然相反。依据MSDN上的解释,有一个很严重的问题没有阐述清楚,那就是:所谓的SetWindowOrg(x, y)函数,到底是表示set window origin to (x, y)还是set window origin as (x, y);to和as在执行的时候,其操作的效果是截然相反的。
set window origin to (x, y)表示将坐标原点设置到(x, y);即以(x, y)作为坐标原点,此时原点坐标不再为(0, 0);set window origin as (x, y)表示将原来的原点(0, 0)的坐标改为(x, y);即将所有点的坐标增加(+x, +y);
现在我的理解是:应该是 set window origin to (x, y)。这种理解基于以下几个前提:1. 所有绘图语句中给出的坐标,全部是逻辑坐标,即在 window 中的坐标(相对于viewport所表示的设备坐标而言);2. 所有用户能看到的点,其设备坐标一定是位于(0, 0)和(1024, 768)范围内;(假设显示器为输出设备,采用MM_TEXT映射方式,且屏幕分辨率为1024*768);3. 所谓“(0,0)就原点,原点的坐标一定就是(0,0)”这种理解,是错误的;4. Viewport中的坐标表示设备坐标;Window中的坐标表示逻辑坐标;5. 当在逻辑坐标中指定新的原点后,在执行映射时,设备坐标的原点一定要与逻辑坐标的新原点重合;反过来也是一样,即两个坐标系的原点一定要重合。
下面举例说明:(MM_TEXT映射模式)
(1)CRect rect(0, 0, 200, 200);dc.rectangle(rect);上面的语句在屏幕的最左上角绘制一个正方形;(因为此时逻辑坐标与设备坐标没有偏移)
(2)dc.SetViewportOrg(100, 100);CRect rect(0, 0, 200, 200);dc.rectangle(rect);将设备坐标的原点设置到(100, 100);即设备坐标的原点不在(0, 0)处,而是在(100, 100)处;此时若执行映射的话,逻辑坐标的原点(0, 0)需要与设备坐标的原点(100, 100)重合(参考前提5);那么此时绘制的矩形(0, 0, 200, 200)的坐标(为逻辑坐标,参考前提1)在设备坐标中就会映射为(100, 100, 300, 300),最终我们在显示器上看到的会是一个向右下方偏移(100, 100)的一个边长为200的正方形(用户看到的点是在设备坐标中的,参考前提2)
(3)dc.SetWindowOrg(100, 100);CRect rect(0, 0, 200, 200);dc.rectangle(rect);将逻辑坐标的原点设置到(100, 100);即逻辑坐标的原点不在(0, 0)处,而是在(100, 100)处;此时若执行映射的话,设备坐标的原点(0, 0)需要与逻辑坐标的原点(100, 100)重合(参考前提5);那么此时绘制的矩形(0, 0, 200, 200)的坐标(为逻辑坐标,参考前提1)在设备坐标中就会映射为(-100, -100, 100, 100),最终我们在显示器上看到的会是一个只有1/4个大小的矩形的一部分(事实上相当于向左上方偏移(100, 100)的一个边长为200的正方形。注意:用户看到的点是在设备坐标中的,参考前提2)
--------------------- 
作者:benny5609 
来源:CSDN 
原文:https://blog.csdn.net/benny5609/article/details/1845645 
版权声明:本文为博主原创文章,转载请附上博文链接!

理解SetWindowOrg,SetViewportOrg,SetWindowExt,SetViewportExt相关推荐

  1. 图形学Bresenham

    1 Bresenham直线 1.1 起始条件 终点坐标 起始点坐标 通过终点坐标和起始点坐标可以得到直线方程: KaTeX parse error: Undefined control sequenc ...

  2. 对SetViewportOrg和SetWindowOrg的理解

    对SetViewportOrg和SetWindowOrg的理解: void CMainWindow::OnLButtonDown(UINT nFlags,CPoint point) {  CRect ...

  3. SetWindowOrg等相关函数

    按习惯,(0,0)就原点,原点就是(0,0),但是如果用此来理解windows的map mode,就会走弯路.其实,稍微改变一下观念,windows的map mode就比较好理解了.举例说明: pag ...

  4. 通用解题法——回溯算法(理解+练习)

    积累算法经验,积累解题方法--回溯算法,你必须要掌握的解题方法! 什么是回溯算法呢? 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就&quo ...

  5. stream流对象的理解及使用

    我的理解:用stream流式处理数据,将数据用一个一个方法去 . (点,即调用) 得到新的数据结果,可以一步达成. 有多种方式生成 Stream Source: 从 Collection 和数组 Co ...

  6. Linux shell 学习笔记(11)— 理解输入和输出(标准输入、输出、错误以及临时重定向和永久重定向)

    1. 理解输入和输出 1.1 标准文件描述符 Linux 系统将每个对象当作文件处理.这包括输入和输出进程.Linux 用文件描述符(file descriptor)来标识每个文件对象.文件描述符是一 ...

  7. java局部变量全局变量,实例变量的理解

    java局部变量全局变量,实例变量的理解 局部变量 可以理解为写在方法中的变量. public class Variable {//类变量static String name = "小明&q ...

  8. 智能文档理解:通用文档预训练模型

    预训练模型到底是什么,它是如何被应用在产品里,未来又有哪些机会和挑战? 预训练模型把迁移学习很好地用起来了,让我们感到眼前一亮.这和小孩子读书一样,一开始语文.数学.化学都学,读书.网上游戏等,在脑子 ...

  9. 熵,交叉熵,散度理解较为清晰

    20210511 https://blog.csdn.net/qq_35455503/article/details/105714287 交叉熵和散度 自己给自己编码肯定是最小的 其他的编码都会比这个 ...

最新文章

  1. 文巾解题 面试题 03.06. 动物收容所
  2. dialog对话框初始化 mfc_MFC中Dialog初始化顺序
  3. 更改SQL Server表所有者的操作方法
  4. pcb过孔漏铜_为什么PCB板在生产中会铜线脱落?
  5. esplise自定义快捷代码补全_【Eclipse】_Eclipse自动补全增强方法 常用快捷键
  6. 【社招/实习】百度大搜索招聘NLP、搜索方向算法工程师!
  7. xssfworkbook excel打开为空白_「Excel」轻松运用 Excel 之“Excel 选项”的 4 个设置
  8. 百度指数、淘宝指数学习笔记
  9. 大连超级计算机,ASC19世界大学生超级计算机竞赛在我校圆满落幕
  10. 值得学习的言语 | 对话技巧 | 开场白
  11. springcloud3-服务到服务调用ribbon及openfeign
  12. Numpy图解(三)--高维数组
  13. 资产证券化(ABS)+ 特殊目的信托(SPV)
  14. 市值暴跌7成,马斯克急了:特斯拉是最有价值的公司!
  15. Google Cloud Platform 注册
  16. 群晖NAS搭建portainer
  17. 使用FreeMarker生成word文档(带图片),word转pdf,预览pdf,pdf下载工具类
  18. 概率论与数理统计---排列组合
  19. 【NOJ1149】【算法实验四】【DP_动态规划】旅游预算/加油站问题
  20. 一位ACMer过来人的心得 (2011-08-04 20:44:18)

热门文章

  1. Java经典面试题:一个线程两次调用start()方法会出现什么情况?
  2. 刚换工作,记录下心得
  3. 【Scratch】青少年蓝桥杯_每日一题_4.13_猫捉老鼠
  4. Android 面试 - compileSdkVersion、minSdkVersion、targetSdkVersion、buildToolsVersion
  5. Android --- 订单编号怎样不重复?一秒钟如果有n个人同时下单怎么解决?凌晨12点限量抢购1000件商品,直到抢完为止订单编号怎么处理?
  6. Android --- 当 item 的数量增加时,ListView 并不能根据所有 item 一共的数量来撑开布局
  7. 451 Research发布《2019年数据中心服务和基础设施预测》
  8. for根据ID去重_Vue中v-for配合key使用的重要性
  9. 成功解决ERROR: Unable to find the development tool `cc` in your path; please make sure that you have the
  10. Dataset之WebVision:WebVision数据集简介、下载、使用方法之详细攻略