坐标系转换,客户区坐标转换成逻辑…

原创 2013年12月02日 15:13:56

客户区坐标转换成逻辑坐标或其它你想要的坐标。

转换坐标核心代码如下,其中最关键的一步为pDC->SetMapMode(MM_LOMETRIC);设置映射模式

CMyDoc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);
 CPen pen(1,5,RGB(0x7A,0x7A,0x7A));
 CClientDC *pDC = new CClientDC(this);

//设置映射模式,单位为0.1mm,引时窗口坐标系以客户区左上角为原点,

                //X轴的方向为从左往右,Y轴的方向为从下往上

 pDC->SetMapMode(MM_LOMETRIC);
 pDC->SelectObject(&pen);
//获得客户区域
 CRect rect;
 GetClientRect(&rect);
//将客户坐标转换为逻辑坐标,
 pDC->DPtoLP(&rect);
//在逻辑坐标下,意图将视口原点所置的位置
 CSize org(200,-rect.bottom-200);
//将该位置转换为设置坐标,方便移动视口坐标原点
 pDC->LPtoDP(&org);

 

 

以上是绘制直角坐标系的部分代码,全部cpp文件代码如下。

 

 

 

// 直角坐标系View.cpp : implementation of the CMyView class
//

#include "stdafx.h"
#include "直角坐标系.h"

#include "直角坐标系Doc.h"
#include "直角坐标系View.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMyView

IMPLEMENT_DYNCREATE(CMyView, CView)

BEGIN_MESSAGE_MAP(CMyView, CView)
 //{{AFX_MSG_MAP(CMyView)
  // NOTE - the ClassWizard will add and remove mapping macros here.
  //    DO NOT EDIT what you see in these blocks of generated code!
 //}}AFX_MSG_MAP
 // Standard printing commands
 ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
 ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
 ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMyView construction/destruction

CMyView::CMyView()
{
 // TODO: add construction code here

}

CMyView::~CMyView()
{
}

BOOL CMyView::PreCreateWindow(CREATESTRUCT& cs)
{
 // TODO: Modify the Window class or styles here by modifying
 //  the CREATESTRUCT cs

 return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CMyView drawing
void CMyView::OnDraw(CDC* pD)
{
 int x_min=10;// x轴起始座标                                                      
    int x_step=10;// 显示间隔
    int y_min=10;// y轴起始座标
    int y_step=10;// 显示间隔
 CMyDoc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);
 CPen pen(1,5,RGB(0x7A,0x7A,0x7A));
 CClientDC *pDC = new CClientDC(this);

//设置映射模式,单位为0.1mm,引时窗口坐标系以客户区左上角为原点,

                //X轴的方向为从左往右,Y轴的方向为从下往上

 pDC->SetMapMode(MM_LOMETRIC);
 pDC->SelectObject(&pen);
//获得客户区域
 CRect rect;
 GetClientRect(&rect);
//将客户坐标转换为逻辑坐标,
 pDC->DPtoLP(&rect);
//在逻辑坐标下,意图将视口原点所置的位置
 CSize org(200,-rect.bottom-200);
//将该位置转换为设置坐标,方便移动视口坐标原点
 pDC->LPtoDP(&org);
//移动视口坐标原点,整个坐标尺在可见区域
 pDC->SetViewportOrg(org.cx,org.cy);
//在逻辑坐标系下画X轴,起点为逻辑坐标系下的原点,终点为自定的
 pDC->MoveTo(0,0);
//X轴的长度为客户区的宽度减去5厘米(一个象素单位为0.1mm),此时X轴终点距右边框的距离将为3cm(视口原点已经移
//动到距左边框2cm处)
 pDC->LineTo(rect.right*2/3,0);


 pDC->MoveTo(rect.right*2/3,0);
 pDC->LineTo(rect.right*2/3-50,20);
 pDC->MoveTo(rect.right*2/3,0);
 pDC->LineTo(rect.right*2/3-50,-20);
 pDC->TextOut(rect.right*2/3,0,L"X");


//在逻辑坐标系下画Y轴,起点为逻辑坐标系下的原点,终点为自定的
 pDC->MoveTo(0,0);
//Y轴的长度为客户区的高度减去5厘米(一个象素单位为0.1mm),此时Y轴终点距上边框的距离将为3cm(视口原点已经移
//动到距下边框2cm处)
 pDC->LineTo(0,-rect.bottom-500);
//以下代码用来画Y轴的终点箭头
 pDC->MoveTo(-20,-rect.bottom-540);
 pDC->LineTo(0,-rect.bottom-500);
 pDC->MoveTo(20,-rect.bottom-540);
 pDC->LineTo(0,-rect.bottom-500);
 pDC->TextOut(0,-rect.bottom-400,_T("Y"));
//在画标尺时,刻度的最大单位为cm,最小单位为mm,坐标轴上只画有整数个cm段,并在相应的位置标明cm刻度
//计算X轴可以画出多少个cm刻度
 int num = (rect.right+1000)/200;
//利用循环画X轴上的刻度,i表示第多少个mm刻度,总共为num*10个毫米刻度
 int k=x_min;
 for(int i = 0;i<=num*10; i++)
 {

//刻度能为5整除,此时的可能值为:5,10,15……
  if(i%5==0)
  {  


//刻度为10的倍数时,画出刻度标记,它的长度为4mm,并在刻度的下方标明刻度值,单位为cm
   if((i ==0)&&(k%x_step==0)) // 间隔为step,默认为20
   {
    pDC->MoveTo(i*10,0);
    pDC->LineTo(i*10,40);
    CString str;
    str.Format(_T("%d"),k);  // 显示刻度
    pDC->TextOut(i*10-10,-10,str);
    k+=x_step;
   }
   else//刻度为5,15等时,画出刻度标记,它的长度为2mm
   {
    pDC->MoveTo(i*10,0);
    pDC->LineTo(i*10,20);
   }

  }
 }


//计算Y轴可以画出多少个cm刻度
 num = (-rect.bottom-500)/100;
 k=y_step;
//相用画X轴上的坐标相同的方法来绘制Y轴坐标,此时注意绘画点的改变
 for(int j = 1;j<=num*10; j++)
 {
  if(j%5==0)
  {
   if((j ==0)&&(k%y_step==0))
   {
    pDC->MoveTo(0,j*10);
    pDC->LineTo(40,j*10);
    CString str;
    str.Format(_T("%d"),k);
    pDC->TextOut(-45,j*10+10,str);
    k+=y_step;
   }
   else
   {
    pDC->MoveTo(0,j*10);
    pDC->LineTo(20,j*10);
   }
  }
 }


 delete pDC;

 // TODO: add draw code for native data here
}

/////////////////////////////////////////////////////////////////////////////
// CMyView printing

BOOL CMyView::OnPreparePrinting(CPrintInfo* pInfo)
{
 // default preparation
 return DoPreparePrinting(pInfo);
}

void CMyView::OnBeginPrinting(CDC* , CPrintInfo* )
{
 // TODO: add extra initialization before printing
}

void CMyView::OnEndPrinting(CDC* , CPrintInfo* )
{
 // TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CMyView diagnostics

#ifdef _DEBUG
void CMyView::AssertValid() const
{
 CView::AssertValid();
}

void CMyView::Dump(CDumpContext& dc) const
{
 CView::Dump(dc);
}

CMyDoc* CMyView::GetDocument() // non-debug version is inline
{
 ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc)));
 return (CMyDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMyView message handlers

 

程序运行结果图如下:

坐标系转换,客户区坐标转换成逻辑坐标

欢迎访问我的小站 船长旅游网,百度搜索  船长旅游网

逻辑坐标与设备坐标——全窗口坐标、屏幕坐标、客户区坐标的总结

Windows应用程序绘制图形时使用的是一种逻辑单位,每个逻辑单位的大小由映射模式决定,这个逻辑单位既可以与设备单位(屏幕或打印机上的一个像素点)相同,也可以是一种物理单位(如毫米),还可以是用户自定...
  • lyh03601
  • lyh03601
  • 2014年03月26日 23:03
  • 2637

windows 屏幕坐标 窗口坐标 客户区坐标 逻辑坐标 设备坐标之间的关系及转换

设置坐标映射    (1)Windows坐标系统 Windows坐标系分为逻辑坐标系和设备坐标系两种,GDI支持这两种坐标系。一般而言, GDI的文本和图形输出函数使用逻辑坐标,而在客户区移...
  • lp310018931
  • lp310018931
  • 2013年11月28日 13:13
  • 6363

MFC 如何获取客户区当前指针的坐标

CRect rect; GetClientRect(&rect);//获取客户区的大小 CPoint point; GetCursorPos(&point);//获取当前指针的坐...
  • scylhy
  • scylhy
  • 2015年07月12日 15:48
  • 1556

屏幕坐标系和窗口客户区坐标系最明显的区别

屏幕坐标系和窗口客户区坐标系最明显的区别在于坐标原点,屏幕坐标系的坐标原点在整个屏幕的左上角,而窗口客户区坐标系的坐标原点在窗口客户区的左上角,通常这两个点是不重合的。 一 设备坐标和逻辑坐标 ...
  • LJH0600301217
  • LJH0600301217
  • 2013年03月29日 15:37
  • 5599

WINDOWS 逻辑坐标 设备坐标 屏幕坐标 客户区坐标

Windows坐标系分为逻辑坐标系和设备坐标系两种,GDI支持这两种坐标系。一般而言, GDI的文本和图形输出函数使用逻辑坐标,而在客户区移动或按下鼠标的鼠标位置是采用设备坐标。 逻辑坐标...
  • memm2
  • memm2
  • 2013年11月28日 18:43
  • 358

WINDOWS 逻辑坐标 设备坐标 屏幕坐标 客户区坐标

设置坐标映射    (1)Windows坐标系统 Windows坐标系分为逻辑坐标系和设备坐标系两种,GDI支持这两种坐标系。一般而言, GDI的文本和图形输出函数使用逻辑坐标,而在客户区移...
  • BEYONDHE_
  • BEYONDHE_
  • 2013年07月20日 14:01
  • 511

MFC中客户区和非客户区概念的图示

 问题: 什么是客户区/非客户区?窗口(框架/frame)的客户区和视图(view)的客户区的区别? 这些都是初学者很容易迷惑的地方,我也是很迷惑,不过经过一番折腾终于弄明白这些问题...
  • c1520006273
  • c1520006273
  • 2016年01月16日 04:05
  • 2812

WINDOWS 逻辑坐标 设备坐标 屏幕坐标 客户区坐标

设置坐标映射    (1)Windows坐标系统 Windows坐标系分为逻辑坐标系和设备坐标系两种,GDI支持这两种坐标系。一般而言, GDI的文本和图形输出函数使用逻辑坐标,而在客户区移...
  • epluguo
  • epluguo
  • 2013年06月30日 23:03
  • 631

windows 屏幕坐标 窗口坐标 客户区坐标 逻辑坐标 设备坐标之间的关系及转换

设置坐标映射    (1)Windows坐标系统 Windows坐标系分为逻辑坐标系和设备坐标系两种,GDI支持这两种坐标系。一般而言, GDI的文本和图形输出函数使用逻辑坐标,而在客户区移...
  • lyzyung
  • lyzyung
  • 2015年01月21日 10:13
  • 889

MFC-客户区与非客户区

客户区
  • godqiao
  • godqiao
  • 2017年11月20日 14:22
  • 120
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:坐标系转换,客户区坐标转换成逻辑…
举报原因:
原因补充:

(最多只允许输入30个字)