分类: C/C++
2007-04-22 11:02:57
在Windows应用程序中,只要进行绘图,就要使用GDI坐标系统。Windows提供了几种映射方式,每一种映射都对应着一种坐标系。例如,绘制图形时,必须给出图形各个点在客户区的位置,其位置用x 和y两个坐标表示,x 表示横坐标,y表示纵坐标。在所有的GDI绘制函数中,这些坐标使用的是一种“逻辑单位”。当GDI函数将结果输出送到某个设备上时,Windows将逻辑坐标转换成设备坐标(如屏幕或打印机的像素点)。本文讨论了图形环境中的各个映射模式,包括它们是什么,怎么工作的,以及它们真正的含义。
一、基础知识
当在微软的窗口中进行绘图时,绘图的坐标原点在屏幕的左上角,任何在屏幕上定位都要参考这个坐标原点。在笛卡尔坐标系统中这个点被定义为坐标原点(0,0),水平坐标轴的正方向是从该点出发向右延伸,垂直坐标轴的正方向是从该点出发向下延伸。
![]() 图一、笛卡尔坐标系 |
CExoDraw1View::OnPaint()
{
CPaintDC dc(this); // 绘图的设备厂上下文
CPen PenBlue;
// 兰色画笔
PenBlue.CreatePen(PS_SOLID, 1, RGB(0, 12, ));
dc.SelectObject(&pPen);
dc.Ellipse(-100, -100, 100, 100);
} |
![]() 图二、代码效果图 |
void CExoDraw1View::OnPaint()
{
CPaintDC dc(this); // 绘图的设备上下文
CRect Recto;
CPen PenBlue;
PenBlue.CreatePen(PS_SOLID, 1, RGB(0, 12, 255));
dc.SelectObject(&PenBlue);
dc.Ellipse(-100, -100, 100, 100);
CPen PenBlack;
PenBlack.CreatePen(PS_SOLID, 1, BLACK_);
dc.SelectObject(&PenBlack);
// 得到客户区域的尺寸;
GetClientRect(&Recto);
dc.MoveTo(Recto.Width() / 2, 0);
dc.LineTo(Recto.Width() / 2, Recto.Height());
dc.MoveTo(0, Recto.Height() / 2);
dc.LineTo(Recto.Width(), Recto.Height() / 2);
} |
![]() |
三、更改坐标系统
正如上面所看到的,默认的坐标系统坐标原点位于窗口的左上角,水平轴的正方向向右,垂直轴的正方向向下。为了进一步说明这一点,让我们来绘制一个半径为50个单位,圆心位于(0,0)点,同时绘制一个连接(0,0)(100,100)两点的直线。
void CExoDraw1View::OnPaint()
{
CPaintDC dc(this); // device context for painting
// A circle whose center is at the origin (0, 0)
dc.Ellipse(-50, -50, 50, 50);
// A line that starts at (0, 0) and ends at (100, 100)
dc.MoveTo(0, 0);
dc.LineTo(100, 100);
} |
![]() 图四、代码效果图 |
MFC提供了各种函数来处理坐标定位及扩展绘制区域的问题,包括在屏幕上任意位置设置坐标原点的函数。因为你是在一个设备上下文上进行绘图操作,因此,你所需要做的就是调用CDC::SetViewportOrg()函数。这个函数重载了两个版本,这允许你使用X、Y坐标或是一个定义的Point点。这个函数的语法如下:
SetViewportOrg(int X, int Y);
SetViewportOrg(CPoint Pt); |
void CExoDraw1View::OnPaint()
{
CPaintDC dc(this); //绘图的设备上下文;
dc.SetViewportOrg(200, 150);
// 圆心位于坐标原点(0, 0)
dc.Ellipse(-50, -50, 50, 50);
// 连接(0, 0) 和 (100, 100)点的直线;
dc.MoveTo(0, 0);
dc.LineTo(100, 100);
} |
![]() 图五、代码效果图 |
void CExoDraw1View::OnPaint()
{
CPaintDC dc(this); //绘图的设备上下文;
CRect Recto;
//获取客户区尺寸;
GetClientRect(&Recto);
dc.SetViewportOrg(Recto.Width() / 2, Recto.Height() / 2);
// A circle whose center is at the origin (0, 0)
dc.Ellipse(-50, -50, 50, 50);
// A line that starts at (0, 0) and ends at (100, 100)
dc.MoveTo(0, 0);
dc.LineTo(100, 100);
} |
![]() 图六、代码效果图 |
void CExoDraw1View::OnPaint()
{
CPaintDC dc(this); // device context for painting
CRect Recto;
dc.SetViewportOrg(380, 220);
// Use a red pen
CPen PenRed(PS_SOLID, 1, RGB(255, 0, 0));
dc.SelectObject(PenRed);
// A circle whose center is at the origin (0, 0)
dc.Ellipse(-100, -100, 100, 100);
// Use a blue pen
CPen PenBlue(PS_SOLID, 1, RGB(0, 0, 255));
dc.SelectObject(PenBlue);
// Horizontal axis
dc.MoveTo(-380, 0);
dc.LineTo(380, 0);
// Vertical axis
dc.MoveTo(0, -220);
dc.LineTo(0, 220);
} |
![]() 图七、代码效果图 |
![]() |
void CExoDraw1View::OnPaint()
{
CPaintDC dc(this); // device context for painting
dc.SetViewportOrg(380, 220);
// Use a red pen
CPen PenRed(PS_SOLID, 1, RGB(255, 0, 0));
dc.SelectObject(PenRed);
// A circle whose center is at the origin (0, 0)
dc.Ellipse(-100, -100, 100, 100);
// Use a blue pen
CPen PenBlue(PS_SOLID, 1, RGB(0, 0, 255));
dc.SelectObject(PenBlue);
// Horizontal axis
dc.MoveTo(-380, 0);
dc.LineTo(380, 0);
// Vertical axis
dc.MoveTo(0, -220);
dc.LineTo(0, 220);
// An orange pen
CPen PenOrange(PS_SOLID, 1, RGB(255, 128, 0));
dc.SelectObject(PenOrange);
// A diagonal line at 45 degrees
dc.MoveTo(0, 0);
dc.LineTo(120, 120);
} |
![]() 图九、代码效果图 |
int SetMapMode(int nMapMode); |
void CExoDraw1View::OnPaint()
{
CPaintDC dc(this); // device context for painting
dc.SetMapMode(MM_TEXT);
dc.SetViewportOrg(380, 220);
// Use a red pen
CPen PenRed(PS_SOLID, 1, RGB(255, 0, 0));
dc.SelectObject(PenRed);
// A circle whose center is at the origin (0, 0)
dc.Ellipse(-100, -100, 100, 100);
// Use a blue pen
CPen PenBlue(PS_SOLID, 1, RGB(0, 0, 255));
dc.SelectObject(PenBlue);
// Horizontal axis
dc.MoveTo(-380, 0);
dc.LineTo(380, 0);
// Vertical axis
dc.MoveTo(0, -220);
dc.LineTo(0, 220);
// An orange pen
CPen PenOrange(PS_SOLID, 1, RGB(255, 128, 0));
dc.SelectObject(PenOrange);
// A diagonal line at 45 degrees
dc.MoveTo(0, 0);
dc.LineTo(120, 120);
} |
![]() 图十、代码效果图 |
![]() 图十一、MM_LOENGLISH映射模式下的坐标系 |
void CExoDraw1View::OnPaint()
{
CPaintDC dc(this); // device context for painting
dc.SetMapMode(MM_LOENGLISH);
dc.SetViewportOrg(380, 220);
. . .
} |
![]() 图十二、代码效果图 |
void CExoDraw1View::OnPaint()
{
CPaintDC dc(this); // device context for painting
dc.SetMapMode(MM_HIENGLISH);
dc.SetViewportOrg(380, 220);
. . . Same as previous
} |
![]() 图十三、代码效果图 |
void CExoDraw1View::OnPaint()
{ CPaintDC dc(this); // device context for painting
dc.SetMapMode(MM_LOMETRIC);
dc.SetViewportOrg(380, 220);
. . .
} |
![]() 图十四、代码效果图 |
void CExoDraw1View::OnPaint()
{
CPaintDC dc(this); // device context for painting
dc.SetMapMode(MM_HIMETRIC);
dc.SetViewportOrg(380, 220);
. . . Same as previous
} |
![]() 图十五、代码效果图 |
void CExoDraw1View::OnPaint()
{
CPaintDC dc(this); // device context for painting
CRect Recto;
dc.SetMapMode(MM_TWIPS);
dc.SetViewportOrg(380, 220);
. . .
} |
![]() 图十六、代码效果图 |
void CExoDraw1View::OnPaint()
{
CPaintDC dc(this); // device context for painting
CPen PenRed(PS_SOLID, 1, RGB(255, 0, 0));
CBrush BrushAqua(RGB(0, 255, 255));
dc.SelectObject(PenRed);
dc.SelectObject(BrushAqua);
// Draw a square with a red border and an aqua background
dc.Rectangle(-100, -100, 100, 100);
CPen BluePen(PS_SOLID, 1, RGB(0, 0, 255));
dc.SelectObject(BluePen);
// Diagonal line at 45 degrees starting at the origin (0, 0)
dc.MoveTo(0, 0);
dc.LineTo(200, 200);
} |
![]() 图十七、代码效果图 |
void CExoDraw1View::OnPaint()
{
CPaintDC dc(this); // device context for painting
dc.SetViewportOrg(340, 220);
CPen PenRed(PS_SOLID, 1, RGB(255, 0, 0));
CBrush BrushAqua(RGB(0, 255, 255));
dc.SelectObject(PenRed);
dc.SelectObject(BrushAqua);
// Draw a square with a red border and an aqua background
dc.Rectangle(-100, -100, 100, 100);
CPen BluePen(PS_SOLID, 1, RGB(0, 0, 255));
dc.SelectObject(BluePen);
// Diagonal line at 45 degrees starting at the origin (0, 0)
dc.MoveTo(0, 0);
dc.LineTo(200, 200);
} |
![]() 图十八、代码效果图 |
void CExoDraw1View::OnPaint()
{
CPaintDC dc(this); // device context for painting
dc.SetMapMode(MM_ISOTROPIC);
dc.SetViewportOrg(340, 220);
CPen PenRed(PS_SOLID, 1, RGB(255, 0, 0));
CBrush BrushAqua(RGB(0, 255, 255));
dc.SelectObject(PenRed);
dc.SelectObject(BrushAqua);
// Draw a square with a red border and an aqua background
dc.Rectangle(-100, -100, 100, 100);
CPen BluePen(PS_SOLID, 1, RGB(0, 0, 255));
dc.SelectObject(BluePen);
// Diagonal line at 45 degrees starting at the origin (0, 0)
dc.MoveTo(0, 0);
dc.LineTo(200, 200);
} |
![]() 图十九、代码效果图 |
CSize SetWindowExt(int cx, int cy);
CSize SetWindowExt(SIZE size); |
void CExoDraw1View::OnPaint()
{
CPaintDC dc(this); // device context for painting
dc.SetMapMode(MM_ISOTROPIC);
dc.SetViewportOrg(340, 220);
dc.SetWindowExt(480, 480);
CPen PenRed(PS_SOLID, 1, RGB(255, 0, 0));
CBrush BrushAqua(RGB(0, 255, 255));
dc.SelectObject(PenRed);
dc.SelectObject(BrushAqua);
// Draw a square with a red border and an aqua background
dc.Rectangle(-100, -100, 100, 100);
CPen BluePen(PS_SOLID, 1, RGB(0, 0, 255));
dc.SelectObject(BluePen);
// Diagonal line at 45 degrees starting at the origin (0, 0)
dc.MoveTo(0, 0);
dc.LineTo(200, 200);
} |
![]() 图二十、代码效果图 |
CSize SetViewportExt(int cx, int cy);
CSize SetViewportExt(SIZE size); |
SetWindowExt(int Lwidth, int Lheight) //参数的单位为逻辑单位(Logical);
SetViewportExt(int Pwidth, int Pheight) //参数的单位为像素(Pixel); |
void CExoDraw1View::OnPaint()
{
CPaintDC dc(this); // device context for painting
dc.SetMapMode(MM_ISOTROPIC);
dc.SetViewportOrg(340, 220);
dc.SetWindowExt(480, 480);
dc.SetViewportExt(440, -680);
CPen PenRed(PS_SOLID, 1, RGB(255, 0, 0));
CBrush BrushAqua(RGB(0, 255, 255));
dc.SelectObject(PenRed);
dc.SelectObject(BrushAqua);
// Draw a square with a red border and an aqua background
dc.Rectangle(-100, -100, 100, 100);
CPen BluePen(PS_SOLID, 1, RGB(0, 0, 255));
dc.SelectObject(BluePen);
// Diagonal line at 45 degrees starting at the origin (0, 0)
dc.MoveTo(0, 0);
dc.LineTo(200, 200);
} |
![]() 图二十一、代码效果图 五、实例代码 为了灵活使用逻辑坐标系,下面给出了几个例子代码:
例1:绘制带箭头的坐标轴
例3:点状网格
例4:正弦图形
|