关于这两个函数的解释,我就不详细叙述了,我的前两篇博客关于这两个函数的内容已经讲的比较清楚了,有需要的同学可以找一找!我只是记录一下我自己使用的心得!

先确定几点:

1.默认的时候,视口坐标原点在屏幕显示部分的左上角。

先来热一下身:
[cpp] view plaincopyprint?![]()
- void CmfcAppView::OnDraw(CDC* pDC)
- {
- CmfcAppDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- if (!pDoc)
- return;
- CRect rect;
- GetClientRect(&rect);
- CBrush brush(RGB(255, 0, 0));
- CPen pen(PS_SOLID, 3, RGB(0, 0, 255));
- pDC->SelectObject(&brush);
- pDC->SelectObject(&pen);
- pDC->SetWindowOrg(100, 100);
- pDC->SetWindowOrg(-100, -100);
- pDC->Rectangle(0, 0, 150, 150);
- }

结果是:

再来看一看这段:
[cpp] view plaincopyprint?![]()
- void CmfcAppView::OnDraw(CDC* pDC)
- {
- CmfcAppDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- if (!pDoc)
- return;
- CRect rect;
- GetClientRect(&rect);
- CBrush brush(RGB(255, 0, 0));
- CPen pen(PS_SOLID, 3, RGB(0, 0, 255));
- pDC->SelectObject(&brush);
- pDC->SelectObject(&pen);
- pDC->Rectangle(0, 0, 150, 150);
- pDC->SetWindowOrg(-100, -100);
- pDC->Rectangle(0, 0, 150, 150);
- }

结果是:

好吧!接下来搞点有技术含量的:
[cpp] view plaincopyprint?![]()
- void CmfcAppView::OnDraw(CDC* pDC)
- {
- CmfcAppDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- if (!pDoc)
- return;
- CRect rect;
- GetClientRect(&rect);
- CBrush brush(RGB(255, 0, 0));
- CPen pen(PS_SOLID, 3, RGB(0, 0, 255));
- pDC->SelectObject(&brush);
- pDC->SelectObject(&pen);
- pDC->SetWindowOrg(100, 100);
- pDC->Rectangle(0, 0, 150, 150);
- }

结果是:

有人奇怪上面的结果了,为什么矩形只剩下大约1/4的位置了?

看一下这段程序:
[cpp] view plaincopyprint?![]()
- void CmfcAppView::OnDraw(CDC* pDC)
- {
- CmfcAppDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- if (!pDoc)
- return;
- CRect rect;
- GetClientRect(&rect);
- CBrush brush(RGB(255, 0, 0));
- CPen pen(PS_SOLID, 3, RGB(0, 0, 255));
- pDC->SelectObject(&brush);
- pDC->SelectObject(&pen);
- pDC->SetViewportOrg(100, 100);
- pDC->Rectangle(0, 0, 150, 150);
- }

想一想结果,然后和真实的结果比对一下:

我的解释如下:

在看一下这段代码,然后猜一下结果?
[cpp] view plaincopyprint?![]()
- void CmfcAppView::OnDraw(CDC* pDC)
- {
- CmfcAppDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- if (!pDoc)
- return;
- CRect rect;
- GetClientRect(&rect);
- CBrush brush(RGB(255, 0, 0));
- CPen pen(PS_SOLID, 3, RGB(0, 0, 255));
- pDC->SelectObject(&brush);
- pDC->SelectObject(&pen);
- pDC->SetViewportOrg(100, 100);
- pDC->SetWindowOrg(-100, -100);
- pDC->Rectangle(0, 0, 150, 150);
- }

让我们来核对一下:

是不是感到有些奇怪?看一下我的解释!

对于上面的第3步,有人感到很奇怪,为什么画矩形的时候是以变换前的逻辑坐标为准的?而不是以变换后的逻辑坐标为准的?

看一下结果的精确测量:

看见没有,测量的结果说明,我上面的原理图是正确的!

关于解释,我的解释是:SetWindowOrg函数并未实际上改变逻辑坐标,只是通知程序应该怎样映射,该把逻辑坐标的这个点映射到视口坐标的哪个点!应该比较清楚了吧?

最好,这两个函数别同时用,因为两个混在一起,很容易糊涂!

既然都讲了这么多了,顺带提一下SetViewportExt和SetWindowExt两个函数吧!这两个函数只在映射模式为MM_ISOTROPIC和MM_ANISOTROPIC下有效!两个函数里面参数的值并不重要,重要的只是他们的比值罢了!

看这段代码:
[cpp] view plaincopyprint?![]()
- pDC->SetMapMode(MM_ANISOTROPIC);
- pDC->SetWindowExt(1024,768);
- pDC->SetViewportExt(10240,7680); //表示一个窗口单位,也就是在x轴上逻辑单位对应10个视口单位,当然屏幕上表示像素,在y轴上亦然
- pDC->Rectangle(0,0,100,100);

和下面这段代码:
[cpp] view plaincopyprint?![]()
- pDC->SetMapMode(MM_ANISOTROPIC);
- pDC->SetWindowExt(10240,7680);
- pDC->SetViewportExt(102400,76800); //表示一个窗口单位,也就是在x轴上逻辑单位对应10个视口单位,当然屏幕上表示像素,在y轴上亦然
- pDC->Rectangle(0,0,100,100);

两者在效果上没有区别!

还有,两者的正负会影响坐标轴的方向!当然,这不是这篇文章的重点!
本文详细解析了视口坐标系与逻辑坐标系在绘图过程中的区别与应用,通过实例代码展示了如何使用SetWindowOrg与SetViewportOrg函数调整绘图区域,并解释了两者在绘图过程中的作用。
1516

被折叠的 条评论
为什么被折叠?



