2024年4月28日发(作者:)

(0,0)

就原点,按习惯,原点就是

(0,0)

,但是如果用此来理解

windows

mapmode

就会走弯路。其实,稍微改变一下观念,windows的mapmode就比较好理解了。

举例说明:

pagespace---->devicespace

pDC->SetMapMode(MM_LOMETRIC);

pDC->SetWindowOrg(40,0);

//这句“设定”pagespace的原点为(40,0),注意,这时(40,0)就是原点,原点就是(40,0)

这个点,其实,(0,0)与原点没有必然联系。这一句对下面的画图函数在pagespace

中所作的图不会有任何影响。一句话:

SetWindowOrg

就是指定一下,

pagespace

中哪个点为原点。

pDC->Rectangle(0,0,100,-100);

pDC->Rectangle(0,-100,50,-200);

同理,SetViewportOrg也是指定一下,devicespace中哪个点为原点,两个坐标系

映射时,两个原点重合。

SetWindowExt设定pagespace的大小,SetViewportOrgExt设定devicespace

的大小,其实,真正有意义的只是两者的比例关系,例如,在一个1024*768的显

示屏上:

pDC->SetMapMode(MM_ISOTROPIC);

pDC->SetWindowExt(10240,7680);

pDC->SetViewportExt(1024,768);

pDC->Rectangle(0,0,100,100);//给出的是逻辑单位,但是具体绘制出来要转化为设

备单位,转化比例由模式确定

就会画一个

10pixels*10pixels

的矩形。其本质就是,

X

方向,每个逻辑单位有

1024/10240个象素,Y方向每个逻辑单位有768/7680个象素。因此,下面的代码

有相同的作用:

pDC->SetMapMode(MM_ISOTROPIC);

pDC->SetWindowExt(102400,76800);

pDC->SetViewportExt(10240,7680);

pDC->Rectangle(0,0,100,100);

两者本质一样,前者更易于理解。

================================

SetWindowOrg和SetViewportOrg这两个函数比较难搞懂,经过本人的google和

实践终于弄明白了这两个函数的本质区别。

dowOrg(x,y)是把设备坐标的原点(视口)映射到逻辑坐标的(X,Y)处(此时

逻辑坐标的原点在(x,y)处,由于两原点需重合,所在要把设备坐标的原点与逻

辑坐标的原点对齐

)

wportOrg(x,y)是把逻辑坐标的原点(窗口)映射到设备坐标的(X,Y)处

注意设备坐标和逻辑坐标的区别:

1.

设备坐标的

X,Y

轴方向是固定的,单位也是固定的,

X

轴向右递增,

Y

向下递增,

单位都是像素。

2.逻辑坐标的X,Y轴方向不固定,单位也不固定,根据选择的映射模式而变化。

有了以上的解释,相信大家应该能明白为什么下面的代码的现实结果会是这样的了

吧。

voidCEx05aView::OnDraw(CDC*pDC)

{

pDC->SetMapMode(MM_LOMETRIC);

pDC->SetWindowOrg(100,100);//

逻辑坐标

pDC->Rectangle(0,0,200,200);

pDC->SetViewportOrg(100,100);

pDC->SelectStockObject(GRAY_BRUSH);

pDC->Rectangle(0,0,200,200);

}

====================================================

建立一个合适的坐标系可以为我们的绘图带来很大的方便。下面介绍一下如何在

VC中建立我们想要的坐标系。

一设备坐标和逻辑坐标

设备坐标(

DeviceCoordinate

)又称为物理坐标(

PhysicalCoordinate

),是

指输出设备上的坐标。通常将屏幕上的设备坐标称为屏幕坐标。设备坐标用对象距

离窗口左上角的水平距离和垂直距离来指定对象的位置,是以像素为单位来表示的,

设备坐标的

X

轴向右为正,

Y

轴向下为正,坐标原点位于窗口的左上角。

逻辑坐标(LogicalCoordinate)是系统用作记录的坐标。在缺省的模式

(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的坐标,如下图

我们可以用以下代码:

voidCTtView::OnDraw(CDC*pDC)

{

CTtDoc*pDoc=GetDocument();

ASSERT_VALID(pDoc);

CRectrect;

GetClientRect(&rect);

pDC->SetMapMode(MM_ANISOTROPIC);

pDC->SetViewportOrg(0,0);

pDC->SetViewportExt(,);

pDC->SetWindowOrg(0,0);

pDC->SetWindowExt(1000,1000);

pDC->MoveTo(50,50);

pDC->LineTo(50,950);

pDC->LineTo(950,950);

pDC->LineTo(50,50);

}

代码分析:

entRect(&rect);取得客户区矩形区域,将其存放在rect中

2.

pDC->SetMapMode(MM_ANISOTROPIC);

设置映射模式

3.通过pDC->SetViewportOrg(0,0);设置逻辑坐标的原点。

4.通过pDC->SetViewportExt(,);和

pDC->SetWindowExt(1000,1000);

来确定逻辑坐标下和设备坐标下的尺寸对应关系

5.在MM_ANISOTROPIC模式下,X轴单位和Y轴单位可以不相同

6.坐标方向的确定方法是如果逻辑窗范围和视口范围符号相同,则逻辑坐标的

方向和视口的方向相同,即

X

轴向右为正,

Y

轴向下为正。

7.如果将显示模式改为MM_ISOTROPIC,那么X轴单位和Y轴单位一定相

同,感兴趣的读者可以自己使一下。

(二)建立以视窗中心为原点的坐标,如下:

用如下代码:

voidCTtView::OnDraw(CDC*pDC)

{

CTtDoc*pDoc=GetDocument();

ASSERT_VALID(pDoc);

CRectrect;

GetClientRect(&rect);

pDC->SetMapMode(MM_ANISOTROPIC);

pDC->SetViewportOrg(/2,/2);

pDC->SetViewportExt(,);

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(/2,/2);设置视口的原点。

2.

pDC->SetViewportExt(,);

pDC->SetWindowExt(1000,-1000);来确定设备坐标和逻辑坐标的单位对应关系。

3.因为逻辑窗范围和视口范围的符号不一致,纵坐标取反,所以Y轴向上为正。

MM_LOENGLISH

MM_HIENGLISH

MM_LOMETRIC

MM_HIMETRIC

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

它们都是

x

值向右方向递增,

y

值向下递减,并且无法改变。它们之间的区别在于

比例因子见下:(我想书上P53页肯定是印错了,因为通过程序实验x值向右方向

也是递增的)

MM_LOENGLISH0.01英寸

MM_HIENGLISH0.001英寸

MM_LOMETRIC0.1mm

MM_HIMETRIC0.01mm

MM_TWIPS1/1440英寸//应用于打印机,一个twip相当于1/20磅,一磅又相当

1/72

英寸。

几乎在所有GDI函数中使用的坐标值都采用的是逻辑单位.WINDOWS需要将逻辑单位转换为”设备单位”,

即像素.这种转换是由映射方式,窗口和视口的原点,以及窗口和视口的范围所控制的.如

dc->TextOut(0,100,”text”);0和100都是逻辑单位,当程序运行后,在窗口中真正显示文本时,将该数值

转换为设备单位,而转换的结果由映射方式,窗口和视口的原点,以及窗口和视口的范围控制.

WINDOWS对所有的消息(如

WM_SIZE,WM_MOUSEMOVE,WM_LBUTTONDOWN,WM_LBUTTONUP),所有的非GDI函数和一

些GDI函数(如GetDeviceCaps函数),永远使用设备坐标.