关闭

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

410人阅读 评论(0) 收藏 举报
分类:

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

转换坐标核心代码如下,其中最关键的一步为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

 

程序运行结果图如下:

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

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

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:35955次
    • 积分:1184
    • 等级:
    • 排名:千里之外
    • 原创:85篇
    • 转载:5篇
    • 译文:0篇
    • 评论:3条
    最新评论