VC++中GDI和GDI+ 的坐标系统介绍
在Windows应用程序中,只要进行绘图,就要使用GDI坐标系统。Windows提供了几种映射方式,每一种映射都对应着一种坐标系。例如,绘制图形时,必须给出图形各个点在客户区的位置,其位置用x 和y两个坐标表示,x 表示横坐标,y表示纵坐标。在所有的GDI绘制函数中,这些坐标使用的是一种“逻辑单位”。当GDI函数将结果输出送到某个物理设备上时,Windows将逻辑坐标转换成设备坐标(如屏幕或打印机的像素点)。本文讨论了图形环境中的各个映射模式,包括它们是什么,怎么工作的,以及它们真正的含义。
一、基础知识
三、更改坐标系统
正如上面所看到的,默认的坐标系统坐标原点位于窗口的左上角,水平轴的正方向向右,垂直轴的正方向向下。为了进一步说明这一点,让我们来绘制一个半径为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);
}
|
![]() 图二十一、代码效果图 |
|
void CExoDraw1View::OnPaint()
{
CPaintDC dc(this); // device context for painting
CBrush bgBrush(BLACK_BRUSH);
dc.SelectObject(bgBrush);
dc.Rectangle(Recto);
dc.SetMapMode(MM_ISOTROPIC);
dc.SetViewportOrg(0, 440);
dc.SetWindowExt(480, 480);
dc.SetViewportExt(440, -680);
CPen PenWhite(PS_SOLID, 1, RGB(255, 255, 255));
dc.SelectObject(PenWhite);
dc.MoveTo(21, 20);
dc.LineTo(21, 75);
// Up arrow
dc.MoveTo(16, 75);
dc.LineTo(21, 90);
dc.LineTo(26, 75);
dc.LineTo(16, 75);
dc.MoveTo(21, 22);
dc.LineTo(75, 22);
// Right arrow
dc.MoveTo(75, 17);
dc.LineTo(90, 22);
dc.LineTo(75, 27);
dc.LineTo(75, 17);
dc.SetBkMode(TRANSPARENT);
dc.SetTextColor(RGB(255, 255, 255));
dc.TextOut(16, 114, ’Y’);
dc.TextOut(100, 32, ’X’);
dc.Rectangle(15, 15, 30, 30);
}
|
![]() 图二十二、代码效果图 |
例2:绘制网格
|
void CExoDraw1View::OnPaint()
{
CPaintDC dc(this); // device context for painting
CRect Recto;
GetClientRect(&Recto);
CBrush bgBrush(BLACK_BRUSH);
dc.SelectObject(bgBrush);
dc.Rectangle(Recto);
CPen PenBlue(PS_SOLID, 1, RGB(0, 0, 255));
dc.SelectObject(PenBlue);
for(int x = 0; x < Recto.Width(); x += 20)
{
dc.MoveTo(x, 0);
dc.LineTo(x, Recto.Height()); }
for(int y = 0; y < Recto.Height(); y += 20)
{ dc.MoveTo(0, y);
dc.LineTo(Recto.Width(), y); }
}
|
![]() 图二十三、代码效果图 |
|
void CExoDraw1View::OnPaint()
{
CPaintDC dc(this); // device context for painting CRect Recto;
GetClientRect(&Recto);
CBrush bgBrush(BLACK_BRUSH); dc.SelectObject(bgBrush);
dc.Rectangle(Recto); for(int x = 0; x < Recto.Width(); x += 20)
{ for(int y = 0; y < Recto.Height(); y += 20)
{ dc.SetPixel(x, y, RGB(255, 255, 255));
} }
}
|
![]() 图二十四、代码效果 |
|
void CExoView::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
dc.SetMapMode(MM_ANISOTROPIC);
dc.SetViewportOrg(340, 220);
dc.SetWindowExt(1440, 1440);
dc.SetViewportExt(-1440, -220);
CPen PenBlue(PS_SOLID, 1, RGB(0, 0, 255));
dc.SelectObject(PenBlue);
// Axes
dc.MoveTo(-300, 0);
dc.LineTo( 300, 0);
dc.MoveTo( 0, -1400);
dc.LineTo( 0, 1400);
// I am exaggerating with the PI value here but why not?
const double PI = 3.141592653589793238462643383279;
// The following two values were chosen randomly by me.
// You can chose other values you like
const int MultiplyEachUnitOnX = 50;
const int MultiplyEachUnitOnY = 250;
for(double i = -280; i < 280; i += 0.01)
{
double j = sin(PI / MultiplyEachUnitOnX * i) * MultiplyEachUnitOnY; dc.SetPixel(i, j, RGB(255, 0, 0));
}
// Do not call CView::OnPaint() for painting messages
}
|
![]() 图二十五、代码效果图 |
3、全窗口坐标,包括一个程序的整个窗口,包括标题条、菜单、滚动条和窗口框,窗口的左上角为(0,0)。使用GetWindowDC得到的窗口设备环境,可以将逻辑单位转换成窗口”坐标。
当在微软的窗口中进行绘图时,绘图的坐标原点在屏幕的左上角,任何物体在屏幕上定位都要参考这个坐标原点。在笛卡尔坐标系统中这个点被定义为坐标原点(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);
}
|
![]() 图二、代码效果图 |
|
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);
}
|
|
VC++中GDI和GDI+ 的坐标系统介绍的更多相关文章
- VC中使用GDI+实现为按钮加载Png图片
http://blog.csdn.net/flyfish1986/article/details/5381605 VC中使用GDI+实现为按钮加载Png图片 http://www.codeprojec ...
- 【vs2013】如何在VS的MFC中配置使用GDI+?
摘自:http://www.cnblogs.com/CSGrandeur/p/3156843.html (已实验,可行) 1.配置GDI+ VS2010自带GDI+,直接使用. (1)首先要添加头文件 ...
- Win32中GDI+应用(五)--GDI与GDI+编程模型的区别
在GDI里面,你要想开始自己的绘图工作,必须先获取一个device context handle,然后把这个handle作为绘图复方法的一个参数,才能完成任务.同时,device context ha ...
- 深度解析VC中的消息传递机制
摘要:Windows编程和Dos编程,一个很大的区别就是,Windows编程是事件驱动,消息传递的.所以,要学好Windows编程,必须 对消息机制有一个清楚的认识,本文希望能够对消息的传递做一个全面 ...
- 深度解析VC中的消息
消息是指什么? 消息系统对于一个win32程序来说十分重要,它是一个程序运行的动力源泉.一个消息,是系统定义的一个32位的值,他唯一的定义了一个事件,向Windows发出一个通知,告诉应用程序某个事情 ...
- 深度解析VC中的消息(转发)
http://blog.csdn.net/chenlycly/article/details/7586067 这篇转发的文章总结的比较好,但是没有告诉我为什么ON_MESSAGE的返回值必须是LRES ...
- VC中句柄、指针、ID之间的转换
win32直接操作的是句柄HANDLE,每个句柄就对应windows窗口,而vc对HANDLE进行类封装,间接操作的都是HANDLE,现在句柄只是类的一个成员变量. 从句柄到指针 CWnd* pWnd ...
- GDI+ 填充背景时,非常多时候不起作用,GDI、GDI+配合运用
在ONDRAW中运行GDI+ 填充背景时,不起作用,不知道什么原因 [cpp] view plaincopy Graphics graphics(pDC->GetSafeHdc()); Bitm ...
- GDI+ 和GDI
GDI:Graphics Device Interface,即图形设备接口,是Windows API的一个重要组成部分.它是Windows图形显示程序与实际物理设备之间的桥梁,GDI使得用户无需关心具 ...
- VC++中StretchBlt图像失真问题的解决办法
在 VC 中使用 StretchBlt 会碰到一些与点阵图大小缩放相关的一些问题.在扩展一个点阵图时,StretchBlt必须复制图素行或列.如果放大倍数不是原图的整数倍,那么此操作会造成产生的图像有 ...
随机推荐
- Spring Boot自定义配置
一.方法 覆盖自动配置很简单,就当自动配置不存在,直接显式地写一段配置.这段显式配置的形式 不限, Spring支持的XML和Groovy形式配置都可以. 二.原理 @ConditionalOnMis ...
- 【转】C#事件、委托、回调的用法与区别
原文地址:http://blog.csdn.net/huang9012/article/details/38753305 事件包括:事件发送者.事件接收者和事件处理程序.关于事件,我们首要知道的是事件 ...
- azkaban平台的使用
最近接触一些大数据的测试,有些hadoop/spark任务在服务器测试不太方便,会放到azkaban上跑 简单写下azkaband的使用流程:包括任务的上传和提交任务到hadoop集群 一 登陆azk ...
- ansible自动化运维工具使用详解
一. ansible 简介 1. ansible ansible是新出现的 自动化 运维工具 , 基于Python研发 . 糅合了众多老牌运维工具的优点实现了批量操作系统配置.批量程序的部署.批量运行 ...
- Dijkstra 调度场算法 Python实现 一
调度场算法(Shunting Yard Algorithm)是一个用于将中缀表达式转换为后缀表达式的经典算法,由 Edsger Wybe Dijkstra 引入,因其操作类似于火车编组场而得名. — ...
- ror笔记2
在rails app的 config 文件夹中新建unicorn.rb内容如下 worker_processes 2 working_directory "/home/mage/boleht ...
- \\IP\e$方式访问服务器的E盘被拒绝是什么原因?
问题:服务器本地管理员的权限,首先访问是被拒绝而不是报用户名密码错误:其次远程桌面服务器是可以访问我个人点的D.E盘的 打开默认共享方法:先在控制面板的“服务”,看SERVER服务是否启动,如果没有启 ...
- 【311】Python 构建 ArcMap 标注表达式
参考:构建标注表达式(官方帮助) 参考:计算字段示例(官方帮助) 说明:以上两者的方法略有不同,一个是通过字段表达式显示标注,一个通过字段计算新的字段,使用的工具方法也不同,前者通过 Layer.la ...
- Eclipse使用时遇到的问题
Java更新之后,Eclipse运行程序时提示 无法找到Java可执行文件 字符串之间判断用.equals,不能用== String a; String b; if(a.equals(b)){...} ...
- Linux实战教学笔记55:开源虚拟化KVM(三)管理虚拟网络
六,管理虚拟网络 [x] Linux网桥基本概念 [x] qemu-kvm支持的网络 [x] 向虚拟机添加虚拟网络连接 [x] 基于NAT的虚拟网络 [x] 基于网桥的虚拟网络 [x] 用户自定义的隔 ...























