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

page space---->device space
pDC->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);

视口(viewport)是对应的概念。视口是与设备相关的一个矩形区域,坐标单位是与设备相关的。窗口的坐标是逻辑坐标,与设备无关。窗口坐标的原点与视口坐标的原点始终对应于同一点。对于同一个图形,用窗口坐标系统表达的该区域的长和宽与视口的坐标系统表达的长和宽是不同的。二者就定义了这两个坐标系统的比例关系。程序作图时,使用的坐标总是是窗口坐标。而实际的显示或输出设备却各有自己的坐标。

详析VC中坐标系的建立

建立一个合适的

坐标系可以为我们的绘图带来很大的方便 。下面介绍一下如何在VC中建立我们想要的坐标系。
一 设备坐标和逻辑坐标
  设备坐标(Device Coordinate)又称为物理坐标(Physical Coordinate),是指输出设备上的坐标。通常将屏幕上的设备坐标称为屏幕坐标。设备坐标用对象距离窗口左上角的水平距离和垂直距离来指定对象的位置,是以像素为单位来表示的,设备坐标的X轴向右为正,Y轴向下为正,坐标原点位于窗口的左上角。
  逻辑坐标(Logical Coordinate)是系统用作记录的坐标。在缺省的模式(MM_TEXT)下,逻辑坐标的方向和单位与设备坐标的方向和单位相同,也是以像素为单位来表示的,X轴向右为正,Y轴向下为正,坐标原点位于窗口的左上角。逻辑坐标和设备坐标即使在缺省模式下其数值也未必一致,除了在以下两种情况下:
  1. 窗口为非滚动窗口
  2. 窗口为滚动窗口,但垂直滚动条位于滚动边框的最上端,水平滚动条位于最左端,但如果移动了滚动条这两种坐标就不一致了。
  在VC中鼠标坐标的坐标位置用设备坐标表示,但所有GDI绘图都用逻辑坐标表示,所以用鼠标绘图时,那么必须将设备坐标转换为逻辑坐标,可以使用CDC 函数DptoLP()将设备坐标转化为逻辑坐标,同样可以用LptoDP()将逻辑坐标转化为设备坐标。

  二 坐标模式
  为了在不同的领域使用逻辑坐标,Windows提供了以下8种坐标模式:
  分别为MM_TEXT、MM_HIENGLISH、MM_LOENGLISH、MM_HIMETRIC、MM_LOMETRIC、MM_TWIPS、MM_ANISOTROPIC和MM_ISOTROPIC。

  三 实例解析
  (一) 建立以左上角为原点,X轴和Y轴为1000的坐标,如下图
  我们可以用以下代码:
  void CTtView::OnDraw(CDC* pDC)
   {
    CTtDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    CRect rect;
    GetClientRect(&rect);

    pDC->SetMapMode(MM_ANISOTROPIC);
    pDC->SetViewportOrg(0,0);
    pDC->SetViewportExt(rect.right,rect.bottom);

    pDC->SetWindowOrg(0,0);
    pDC->SetWindowExt(1000,1000);

    pDC->MoveTo(50,50);
    pDC->LineTo(50,950);
    pDC->LineTo(950,950);
    pDC->LineTo(50,50);
   }
  代码分析:
  1. GetClientRect(&rect); 取得客户区矩形区域,将其存放在rect中
  2. 用pDC->SetMapMode(MM_ANISOTROPIC); 设置映射模式
  3. 通过pDC->SetViewportOrg(0,0);设置逻辑坐标的原点。
  4. 通过pDC->SetViewportExt(rect.right,rect.bottom);和 
pDC->SetWindowExt(1000,1000);来确定逻辑坐标下和设备坐标下的尺寸对应关系
  5. 在MM_ANISOTROPIC模式下,X轴单位和Y轴单位可以不相同
  6. 坐标方向的确定方法是如果逻辑窗范围和视口范围符号相同,则逻辑坐标的方向和视口的方向相同,即X轴向右为正,Y轴向下为正。
  7. 如果将显示模式改为MM_ISOTROPIC,那么X轴单位和Y轴单位一定相同,感兴趣的读者可以自己使一下。
  (二) 建立以视窗中心为原点的坐标,如下:
  用如下代码:
  void CTtView::OnDraw(CDC* pDC)
   {
    CTtDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    CRect rect;
    GetClientRect(&rect);

    pDC->SetMapMode(MM_ANISOTROPIC);
    pDC->SetViewportOrg(rect.right/2,rect.bottom/2);
    pDC->SetViewportExt(rect.right,rect.bottom);

    pDC->SetWindowOrg(0,0);
    pDC->SetWindowExt(1000,-1000);

    pDC->MoveTo(150,150);
    pDC->LineTo(-150,-200);
    pDC->LineTo(150,-150);
    pDC->LineTo(150,150);
   }
 代码分析:
  1. 用 pDC->SetViewportOrg(rect.right/2,rect.bottom/2); 设置视口的原点。
2. 用pDC->SetViewportExt(rect.right,rect.bottom);和pDC->SetWindowExt(1000,-1000);来确定设备坐标和逻辑坐标的单位对应关系。
  3. 因为逻辑窗范围和视口范围的符号不一致,纵坐标取反,所以Y轴向上为正。

MM_LOENGLISH、MM_HIENGLISH、MM_LOMETRIC、MM_HIMETRIC、MM_TWIPS这一组是Windows提供的重要的固定比例映射模式。

它们都是x值向右方向递增,y值向下递减,并且无法改变。它们之间的区别在于比例因子见下:(我想书上P53页肯定是印错了,因为通过程序实验x值向右方向也是递增的)

MM_LOENGLISH 0.01英寸 
MM_HIENGLISH 0.001英寸 
MM_LOMETRIC 0.1mm 
MM_HIMETRIC 0.01mm 
MM_TWIPS 1/1440英寸 //应用于打印机,一个twip相当于1/20磅,一磅又相当于1/72英寸。

SetWindowOrg等相关函数相关推荐

  1. Python菜鸟学习手册14----标准库+代码实例

    Python Standard Library 翻译: Python 江湖群 10/06/07 20:10:08 编译 0.1. 关于本书 0.2. 代码约定 0.3. 关于例子 0.4. 如何联系我 ...

  2. RTTI(三)相关函数1【转自大富翁】

    第三部分RTTI相关函数 GetTypeData 函数 GetPropInfo 函数 FindPropInfo 函数 GetPropInfos 函数 SortPropList 函数 GetPropLi ...

  3. Windows/Linux上使用fopen相关函数读取大文件

    在介绍读取大文件之前,先了解下<cstdint>文件,标准头文件,存放固定宽度整数类型,如int32_t, uint32_t,不管在32位上还是64位上,长度都为4个字节:int64_t, ...

  4. C++11容器中新增加的emplace相关函数的使用

    C++11中,针对顺序容器(如vector.deque.list),新标准引入了三个新成员:emplace_front.emplace和emplace_back,这些操作构造而不是拷贝元素.这些操作分 ...

  5. go语言中fmt包中Print、Printf、Println输出相关函数的区别

    go语言中fmt包中Print.Printf.Println输出相关函数的区别 区别: Print系列函数将内容输出到系统的标准输出.其区别:Print函数式直接输出内容,Printf函数支持格式化输 ...

  6. java File类 常用相关函数

    java File类 相关函数 1.构建函数 2.判断相关函数 4.创建相关函数 5.删除相关函数 6.获取相关函数 1.构建函数 /*** File 构造方法* file 常用构造方法* 1: Fi ...

  7. Matlab 图像处理相关函数命令大全

    一.通用函数: colorbar  显示彩色条 语法:colorbar \ colorbar('vert') \ colorbar('horiz') \ colorbar(h) \ h=colorba ...

  8. Linux中表示“时间”的结构体和相关函数

    转载于:http://blog.chinaunix.net/uid-25909722-id-2827364.html Linux中表示"时间"的结构体和相关函数 2011-09-1 ...

  9. FFmpeg(五) 重采样相关函数理解

    一.重采样流程 重采样(解码音频数据之后格式不可以直接播放,需要重采样,类似图像的像素转换) 1.分配上下文 2.设置参数(分为(前几个是)输出格式和(后几个)输入格式,两个相对应的) 可以通过改变样 ...

最新文章

  1. Eigen:C++中Eigen库的安装与学习
  2. 深入浅出NIO之Channel、Buffer
  3. android 蓝牙传输分包,彻底掌握Android多分包技术(一)
  4. 1.4 第一个Python程序
  5. 【渝粤教育】国家开放大学2019年春季 1308外国文学专题 参考试题
  6. 数据库 Oracle数据库对象二
  7. 植保___农药基础知识
  8. 西门子smartclient怎么用_西门子200SMART PLC软件各功能怎么用?编程必备!
  9. html插入精灵,帮助插入超链接到CSS精灵代码..Java? HTML?
  10. ubuntu之在ubuntu16.04中搭建gitlab服务器
  11. 互联网广告类型的分析--弹出式广告【3】
  12. 常用原型图绘制工具比较
  13. 怎么把动图分解成图片?gif怎么拆分成几张?
  14. [翻译] ogre 2.0 移植手册 - 4 合成器
  15. Windows 10操作系统常用快捷键介绍
  16. 哪款蓝牙耳机性价比最高?2023性价比高的蓝牙耳机推荐
  17. 德鲁克:CEO必须秉持的六项原则
  18. 作为Gatekeeper,请守好交付质量关口(Quality Gate)
  19. wps怎么把ppt里的字体一起保存_如何将特殊字体随PPT一起保存?
  20. 莫比乌斯反演-小总结

热门文章

  1. python3.6.4安装教程-centos7中安装python3.6.4的教程
  2. 自学网python教程视频-Python爬虫之Django视频教程
  3. python的快速入门-Python如何快速入门的基础知识
  4. 简明python教程在线-Python简明教程
  5. python的GUI库PyQt5的使用
  6. mysql日常有哪些用_mysql日常笔记(持续更新)
  7. 路由在express中的实践
  8. LeetCode Ransom Note(字符串)
  9. LeetCode Reorder List
  10. LeetCode Minimum Path Sum(动态规划)