vc中坐标映射

关于vc中坐标映射的学习心得

一、理论准备

首先在深入vc学习坐标映射的相关知识前,我们必须要知道两个不同的平面直角坐标系应该如和进行转换。

 

 

 

逻辑坐标系:顾名思义,既然是逻辑的,也就是我们想象的。它是不受任何设备因素的限制的。这极其类似于平面几何中直角坐标系,原点我们可以任意定,x轴,y轴的相对方向和位置可以任意定,定义原点之后,我们可以以任意的长度进行绘图,平面空间无限大。可以这样说,逻辑坐标系没有单位可言,因为他是脱离物理设备的。

 

设备坐标系:由于各种原因,大多数是因为历史原因,我们的设备坐标系的原点、x轴、y轴方向是固定的。即物理设备的左上角点为原点(00),x轴水平向右增大,y轴垂直向下增大,单位是像素。记住,设备坐标系得坐标系的以上各种属性永远不会发生变化,至少在vc中。

 

窗口(window):可以这样理解,在vc中窗口就好比我们的绘图板,采用逻辑坐标系。

 

视口(viewport):顾名思义,是我们用来观察窗口的一个取景器,自然是物理设备,采用的是设备坐标系。

 

写到这里,问题就来了,我们如何使用视口来观察窗口呢,呵呵。这就是我们经常搞不清楚的。换句话说,如何使用设备坐标系来展示我们的逻辑坐标系。

 

让我们抛开vc的繁文缛节,暂时超脱红尘,返璞归真的想一下,如果是你你会怎么做呢?

logicalH

deviceH

首先我们想到的是把坐标系的单位统一一下,也就是我们在逻辑坐标系上的一个单位长度1,换算成多少像素。于是我们定义两个矩形,让他们分别代表逻辑坐标系和设备坐标系上的矩形。

 

 

 

deviceW

 

 

逻辑矩形

 

logicalW

 

 

 

 

设备矩形

 

 

 

 

 

 

 

 

 

 

 


因此逻辑长度/设备长度=logcialH/deviceH=logicalW/deviceW。这又带来了一个问题,logcialH/deviceHlogicalW/deviceW如果不相等怎么办呢?于是我们又有了两个方案。一个是在两个方向上使用不同的逻辑和设备比率,另一个是在两个方向上采用同样的逻辑和设备比率,具体采用哪一个都可以。到目前为止,我们已经解决了逻辑与设备的数值转换问题。

然而,可以想象假设一个逻辑的点叫做(5060)那么他转换成设备的点时,坐标是多少呢?你当然想到了,我们应该让逻辑和设备坐标的原点(00)重合,因为逻辑和设备的点坐标都是相对于他们的原点而言的,非常好。但是我们为什么不能够更加灵活一点呢,我们设定一个逻辑点A,和一个设备点B,同时要求在进行转换时AB两点必须重合,这样既使得逻辑和设备的转换有了参照系,又可以让两个坐标系之间进行相互的平移。哇,我们不知不觉已经完成了逻辑坐标到设备坐标的转换,呵呵。

       然而,我们知道目前我们所说的设备坐标的单位是像素,那么像素又是什么呢?按照我们的理解,对于显示器、打印机等显示设备而言,像素就是它们可以输出的最小的一个点。天哪,问题又来了,看来像素也不是真实的、物理的度量单位,因为只要输出设备不同,我们就不敢保证他们所能够打印的最小的点的大小是相同的。以一英寸为例,在不同的输出设备上,组成他们的点的个数是不一样的,换句话说,一英寸长度所包含的像素的个数是不一样的。呵呵,我们当然不是上帝,也不是天才。前辈们自然已经解决了这个问题,他们定义了设备的输出分辨率,DPI,叫做dots per inch,中文叫做点每英寸。

       是不是很有意思呢?呵呵,逻辑坐标,设备坐标,最后才是真实的、我们在日常生活中用到的英寸、厘米啦之类的公制单位。因此,对于如上的事实进行一个总结。

       为了在显示输出设备上进行打印或显示,我们必须具备以下几个条件:

1.         逻辑坐标系的x,y轴的方向

2.         设备坐标系的x,y轴的方向(windows中已经固定,且设备左上角点为原点)

3.         映射的重合点

4.         比例矩形,用来设定在x,y方向上逻辑到设备尺寸的转换比率(L/D=k

5.         显示设备的分辨率,定义了设备像素和真实的物理尺寸之间的比率关(m个设备像素构成 一英寸 )

现在我们来模拟计算一下长度为ll的逻辑长度换算成 一英寸 的过程

ll=ll/k 个像素=ll/k * (1/m) 英寸=ll/(k*m)英寸

我们也可以理解为每一个逻辑单位等于1/(k*m)英寸,我们姑且称之为逻辑单位的真实尺寸

二、Vc中的相关映射模式

为了方便广大用户使用,盖茨大哥已经为我们事先设定一些上述条件,并将它们称之为映射模式。总共有三大类。

l         MM_TEXT

l         MM_LOENGLISHMM_HIENGLISHMM_LOMETRICMM_HIMETRICMM_TWIPS

l         MM_ISOTROPICMM_ANISOTROPIC

 

 

 


 

 

逻辑坐标

设备坐标

映射重合点

比例矩形

逻辑单位的真实尺寸

 

x

y

x

y

逻辑点A

设备点B

逻辑矩形

设备矩形

 

MM_TEXT

→增大

↓增大

增大

增大

默认为(0,0)

 

SetWindowOrg

可以修改

默认为(0,0)

 

SetViewportOrg

可以修改

系统提供,固定

系统提供,固定

1逻辑单位=1像素

MM_LOENGLISH

增大

增大

1逻辑单位=0.01英寸

MM_HIENGLISH

1逻辑单位=0.001英寸

MM_LOMETRIC

1逻辑单位=0.1毫米

MM_HIMETRIC

1逻辑单位=0.01毫米

MM_TWIPS

1逻辑单位=1/120个像素

MM_ISOTROPIC

SetWindowExt(lw,lh)SetViewportExt(dw,dh)共同决定,lwdw的符号相同时,逻辑坐标X和设备坐标X同向→增大,否则反向←增大。lhdh同理。

SetWindowExt(lw,lh)

SetViewportExt(dw,dh)

X,y两个方向的比率必须相同,如果lw/dwlh/dh的比率不同则采用较小的那个。

MM_ANISOTROPIC

X,y轴可以采用不同的比率,各自保持。


三、VC中几个重要的和坐标系相关的函数的说明

pDC->GetDeviceCaps:得到的数据都是设备坐标,单位是像素,最左上角为原点,x向右增大,y向下增大

 

pDC->SetViewportOrgSetViewportExt使用的都是设备坐标系,单位都是像素。你可以把它们看作是你的取景器,要么是显示器上的窗口,要么是空白的打印纸。

 

pDC->SetWindowOrgSetWindowExt使用的都是逻辑坐标系,

 

CPoint,CRect,CSize他们则是一些普通的类,用来承数据而已,可以放置逻辑或设备坐标,就像水桶一样,装水可以,装粥也可以。这完全取决于你。

 

GetClientRect CWnd的一个成员函数,目的是得到客户区域的大小,自然也是设备坐标系,得到的是像素。

                                

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
VC 使用内存映射技术可以显著提高对大文件的读写速度。下面是一个简单的示例代码: ```c++ #include <iostream> #include <windows.h> using namespace std; int main() { HANDLE hFile; HANDLE hMapping; LPVOID lpMapping; // 打开文件 hFile = CreateFile("largefile.bin", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { cout << "Failed to open file." << endl; return 1; } // 创建文件映射 hMapping = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL); if (hMapping == NULL) { cout << "Failed to create file mapping." << endl; CloseHandle(hFile); return 1; } // 映射文件到内存 lpMapping = MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0); if (lpMapping == NULL) { cout << "Failed to map file to memory." << endl; CloseHandle(hMapping); CloseHandle(hFile); return 1; } // 读写文件 char* pFile = (char*)lpMapping; for (int i = 0; i < 4 * 1024 * 1024 * 1024LL; i++) { pFile[i] = i % 256; } // 解除内存映射 UnmapViewOfFile(lpMapping); // 关闭文件映射和文件句柄 CloseHandle(hMapping); CloseHandle(hFile); cout << "Done." << endl; return 0; } ``` 这个示例程序打开一个名为 largefile.bin 的文件,并将其映射到内存。然后,程序将对文件进行读写操作,最后解除内存映射并关闭文件。在这个示例,我们使用了一个 4GB 的文件进行测试,程序可以在较短的时间内完成读写操作,而不会出现内存不足的错误。 需要注意的是,内存映射虽然可以提高文件读写速度,但也会占用一定的内存空间。因此,在使用内存映射技术时,需要根据实际情况选择合适的文件大小和内存使用量。同时,需要注意内存映射可能会对程序的稳定性产生影响,特别是在进行大量读写操作时。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值