[Programming Visual C++]Chapter Four - Mapping Modes

博客介绍了在C/C++里将窗口原点设置到逻辑坐标空间(100, 100),并绘制200×200像素正方形的代码。还提及不同映射模式下逻辑单位和坐标轴方向的差异,给出绘图代码示例,最后探讨何时使用各系统的规则。
1.MM_TEXT

In MM_TEXT, coordinates map to pixels,
values of x increase as you move right,
and values of y increase as you move down,
but you're allowed to change the origin through calls to the CDC functions SetViewportOrg and SetWindowOrg

Here's some code that sets the window origin to (100, 100) in logical coordinate space and then draws a 200-by-200-pixel square offset by (100, 100).

The logical point (100, 100) maps to the device point (0, 0).A scrolling window uses this kind of transformation.

void CMyView::OnDraw(CDC* pDC)
{
pDC->SetMapMode(MM_TEXT);
pDC->SetWindowOrg(CPoint(100, 100));
pDC->Rectangle(CRect(100, 100, 300, 300));
}
屏幕上看到的是顶点在左上角的200*200的方框。


2.MM_HIMETRIC

If you assign the MM_HIMETRIC mapping mode, for example, a logical unit is 1/100 millimeter (mm) instead of 1 pixel.

In the MM_HIMETRIC mapping mode, the y axis runs in the opposite direction to that in the MM_TEXT mode:
y values decrease as you move down.

Thus, a 4-by-4-cm square is drawn in logical coordinates this way:
pDC->Rectangle(CRect(0, 0, 4000, -4000));

3.The Fixed-Scale Mapping Modes

Mapping ModeLogical Unit
MM_LOENGLISH0.01 inch
MM_HIENGLISH0.001 inch
MM_LOMETRIC0.1 mm
MM_HIMETRIC0.01 mm
MM_TWIPS1/1440 inch

in the MM_HIMETRIC mapping mode,
x
values increase as you move right
and y values decrease as you move down.

1 twip = 1/ 20 point
1 point = 1/ 72 inch
=> 12-point = 12 × 20 = 240 twips

4. The Variable-Scale Mapping Modes
Windows provides two mapping modes, MM_ISOTROPIC and MM_ANISOTROPIC, that allow you to change the scale factor as well as the origin. With these mapping modes, your drawing can change size as the user changes the size of the window. Also, if you invert the scale of one axis, you can "flip" an image about the other axis and you can define your own arbitrary fixed-scale factors.

x scale factor = x viewport extent / x window extent
y scale factor = y viewport extent / y window extent
device x = logical x × x scale factor + x origin offset
device y = logical y × y scale factor + y origin offset

Suppose the window is 448 pixels wide ( rectClient.right). The right edge of the ellipse's client rectangle is 500 logical units from the origin. The x scale factor is 448/ 1000, and the x origin offset is 448/ 2 device units. If you use the formulas shown on the previous page, the right edge of the ellipse's client rectangle comes out to 448 device units, the right edge of the window. The x scale factor is expressed as a ratio (viewport extent/window extent) because Windows device coordinates are integers, not floating-point values. The extent values are meaningless by themselves.

5.Coordinate Conversion

Your job is to decide when to use each system. Here are a few rules of thumb:

Assume that the CDC member functions take logical coordinate parameters. Assume that the CWnd member functions take device coordinate parameters. Do all hit-test operations in device coordinates. Define regions in device coordinates. Functions such as CRect::PtInRect work best with device coordinates. Store long-term values in logical or physical coordinates. If you store a point in device coordinates and the user scrolls through a window, that point is no longer valid.

Suppose you need to know whether the mouse cursor is inside a rectangle when the user presses the left mouse button. The code is shown here.

// m_rect is CRect data member of the derived view class with MM_LOENGLISH
// logical coordinates

void CMyView::OnLButtonDown(UINT nFlags, CPoint point)
{
CRect rect = m_rect; // rect is a temporary copy of m_rect.
CClientDC dc(this); // This is how we get a device context
// for SetMapMode and LPtoDP
// -- more in next chapter
dc.SetMapMode(MM_LOENGLISH);
dc.LPtoDP(rect); // rect is now in device coordinates
if (rect.PtInRect(point)) {
TRACE("Mouse cursor is inside the rectangle.\n");
}
}
posted on 2005-07-25 15:22 浙林龙哥 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/huqingyu/archive/2005/07/25/199702.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值