基于VC++的GDI常用坐标系统及应用

在Windows应用程序中,只要进行绘图,就要使用GDI坐标系统。Windows提供了几种映射方式,每一种映射都对应着一种坐标系。例如,绘制图形时,必须给出图形各个点在客户区的位置,其位置用x 和y两个坐标表示,x 表示横坐标,y表示纵坐标。在所有的GDI绘制函数中,这些坐标使用的是一种“逻辑单位”。当GDI函数将结果输出送到某个物理设备上时,Windows将逻辑坐标转换成设备坐标(如屏幕或打印机的像素点)。本文讨论了图形环境中的各个映射模式,包括它们是什么,怎么工作的,以及它们真正的含义。

  一、基础知识    

 (一)逻辑坐标。逻辑坐标与设备无关,缺省地,一个逻辑单位等于设备中的一个象素。它是实现“所见即所得”的基础。例如,当程序员调用LineTo函数绘制25.4mm(1 英 寸) 长的直线时,他只要使用合适的映射模式,那么就并不需要考虑输出的是何种设备。若设备是VGA显示器,Windows自动将其转化为96个像素点;若设备是一个300dpi的激光打印机,Windows自动将其转化为300 个像素点。     

(二)设备坐标。图形输出时,Windows将GDI函数中指定的逻辑坐标映射为设备坐标,在所有的设备坐标系统中,单位以像素点为准,水平值从左到右增大(正方向向右),垂直值从上到下增大(正方向向下)。Windows中包括以下3 种设备坐标,以满足各种不同需要:     

1、客户区域坐标,包括应用程序的客户区域,客户区域的左上角为(0, 0)。     

2、屏幕坐标,包括整个屏幕,屏幕的左上角为(0, 0)。屏幕坐标用在WM_MOVE消息中(对于非子窗口)以及下面的Windows 函数中:CreateWindow 和MoveWindow(都对于非子窗口)、GetMessage、GetCursorPos、GetWindowRect、WindowFromPoint 和SetBrushOrg 中。 用函数ClientToScreen 和ScreenToClient可以将客户区域坐标转换成屏幕区域坐标,或反之。    

3、全窗口坐标,包括一个程序的整个窗口,包括标题条、菜单、滚动条和窗口框,窗口的左上角为(0,0)。使用GetWindowDC得到的窗口设备环境,可以将逻辑单位转换成窗口”坐标。  

  (三)映射。映射方式定义了Windows如何将GDI函数中指定的逻辑坐标映射为设备坐标。在下文中我们将介绍常用的映射方式。    此外,习惯上,我们将逻辑坐标所在的坐标系称为“窗口”;将设备坐标所在的坐标系称为“视口”。“窗口”依赖于逻辑坐标,可以是像素点、毫米或其他尺度。这一点请牢记,这对于下面的有关内容的理解至关重要。 

 二、默认的坐标系统   当在微软的窗口中进行绘图时,绘图的坐标原点在屏幕的左上角,任何物体在屏幕上定位都要参考这个坐标原点。在笛卡尔坐标系统中这个点被定义为坐标原点(0,0),水平坐标轴的正方向是从该点出发向右延伸,垂直坐标轴的正方向是从该点出发向下延伸。

图一、笛卡尔坐标系

  这个坐标原点只是操作系统默认的坐标原点,所以如果你调用Ellipse(-100, -100, 100, 100)函数来绘制图形的话,你将得到一个圆,它的圆心位于屏幕的左上角,仅仅只有圆的四分之一部分(270度到360度的部分)显示在屏幕上。代码及效果图如下

 

void CExoDraw1View::OnPaint() 
{
 CPaintDC dc(this); // 绘图的设备厂上下文
 CPen PenBlue;
 // 兰色画笔
 PenBlue.CreatePen(PS_SOLID, 1, RGB(0, 12,  255));
 dc.SelectObject(&pPen);
 dc.Ellipse(-100, -100, 100, 100);
}

   图二、代码效果图 

  按照同样的原理,你可以使用CpaintDC的方法或按照你的要求创建函数来绘制任何几何或非几何图形。例如,下面的代码绘制了两条相互垂直的直线,垂点位与窗口的中心: 
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_ PEN);
 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);
}
图四、代码效果图
 
  这种默认的坐标原点在大多数图形操作情况下是适用的,但并不是总适用,有时你需要控制坐标系统的原点,例如,很多CAD(图形辅助设计)应用程序就需要用户来定义坐标系统的原点。 
  MFC提供了各种函数来处理坐标定位及扩展绘制区域的问题,包括在屏幕上任意位置设置坐标原点的函数。因为你是在一个设备上下文上进行绘图操作,因此,你所需要做的就是调用CDC::SetViewportOrg()函数。这个函数重载了两个版本,这允许你使用X、Y坐标或是一个定义的Point点。这个函数的语法如下: 
SetViewportOrg(int X, int Y);
SetViewportOrg(CPoint Pt);
 
  调用这个函数时只需要简单地说明哪儿是你想定义的坐标原点,如果使用函数的第二个版本,参数可以是一个POINT结构或是一个MFC提供的Tpoint类。为了演示这个函数的效果,让我们将上例的坐标原点沿X轴正方向移动200个单位,Y轴正方向移动150个单位,这时绘制函数如下:
 
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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
基于GDI图形设备接口)技术的VC(Visual C++)公交线路查询系统是一种利用计算机软件和硬件设备结合的系统。该系统的目的是为了方便用户查询公交线路相关信息。 首先,该系统将通过数据库存储和管理公交线路的相关信息,包括车辆信息、站点信息以及线路信息。用户可以通过系统的界面输入起始站点和终点站点,系统将根据用户输入的信息从数据库中查询相关线路信息,并以图形化方式展示。 其次,系统利用GDI技术实现了地图显示功能。基于地图数据,系统可以使用绘图功能将公交线路标示在地图上。用户可以通过鼠标点击或拖动操作来放大、缩小和平移地图,以查看更多线路细节。 此外,系统还可以通过GDI技术实现公交线路的可视化展示。用户可以选择查看某一线路的具体站点和到站时间。系统将根据用户选择的线路,在地图上显示线路和站点,并以不同颜色和符号区分不同线路。 最后,系统还提供其他功能,比如站点搜索功能。用户可以输入关键字搜索相关站点,系统将根据关键字从数据库中查询相关信息,并在地图上标示出搜索到的站点。此外,用户还可以通过系统了解公交线路的运行时间和票价等信息。 综上所述,基于GDI技术的VC公交线路查询系统能够方便用户查询相关线路信息,提供图形化的展示和交互界面,使用户能够更直观、方便地查找所需信息。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值