MFC+Direct2D简化坐标缩放

来源:互联网 发布:mac finder 侧边栏 编辑:程序博客网 时间:2024/04/30 02:09

背景

问题由来

在参考1这篇文章里写了GDI下坐标缩放的情况,这里记录下再Direct2D绘图引擎下的缩放操作。

环境配置

参考文章2

几个概念

参考上一篇文章的说明配图
配图1
配图2

实现功能

1.所有图形初始缩放在默认视图框架内
2.(0,0)位置位于视图左下角
3.可以从屏幕坐标反推出原始数据坐标
4.使用Direct2D技术,在保持抗锯齿效果的同时,绘图效率和GDI差不多

思路及代码

流程图

Created with Raphaël 2.1.0

计算等效初始坐标

1.遍历原始坐标获得XMAX,YMAX,XMIN,YMIN.
2.获得视窗访问WIDTH,HEIGHT.
3.计算初始缩放比率SCALE,计算方法为:

if(YMAXYMINHEIGHT>XMAXXMINWIDTH),SCALE=HEIGHTYMAXYMIN

if(YMAXYMINHEIGHT<XMAXXMINWIDTH),SCALE=WIDTHXMAXXMIN

同时得到绘图范围

RANGEX=(XMAXXMIN)SCALE

RANGEY=(YMAXYMIN)SCALE

4.计算等效初始坐标,计算方法为:

xnew=(xoldXMIN)SCALE

ynew=(yoldYMIN)SCALE+RANGEY

其中乘以负的缩放系数并加上绘图范围的Y值是为了将坐标调整为y正向向上,左下角为(0,0)
5.反推原始数据
为了从屏幕坐标反推得到原始数据,必须传入视图滚动条位置信息ScrollPT及视图缩放系数Zoom(注意不是初始缩放系数SCALE)
计算方法为:

xold=xscreen+ScrollPT.xZoomSCALE+XMIN

yold=yscreen+ScrollPT.yZoomRANGEYSCALE+YMIN

代码

//.h文件 //一些结构定义typedef std::vector<CPoint> vPT; typedef D2D1_POINT_2F DPoint;typedef std::vector<DPoint> vDPT; typedef D2D1::Matrix3x2F Matrix;typedef struct _InitOffset{//初始化时显示参数    int nXOffset;    int nYOffset;    double dInitScale;    CSize range;    _InitOffset()    {        nXOffset = 0;        nYOffset = 0;        dInitScale = 1.0;        range.cx = 1;        range.cy = 1;    }}InitOffset;typedef struct _ZoomOffset{//初始显示完成之后缩放时显示参数    CPoint ScrolPT;    double dZoom;    _ZoomOffset()    {        ScrolPT = CPoint(0,0);        dZoom = 1.0;    }}ZoomOffset;typedef struct _ScreenPara{//显示参数    InitOffset initoffset;    ZoomOffset zoomoffset;inline  CPoint GetOriginPTFromScreenPT(CPoint ScreenPT)    {        CPoint PT;        PT.x = (ScreenPT.x + zoomoffset.ScrolPT.x) / (zoomoffset.dZoom * initoffset.dInitScale)             + initoffset.nXOffset ;        PT.y = ((ScreenPT.y  + zoomoffset.ScrolPT.y) / zoomoffset.dZoom - initoffset.range.cy) /             -initoffset.dInitScale + initoffset.nYOffset;        return(PT);    }inline  CSize GetZoomRange(void)    {        return(CSize(initoffset.range.cx * zoomoffset.dZoom,            initoffset.range.cy * zoomoffset.dZoom));    }}ScreenPara;extern ScreenPara g_ScreenPara;
//.cpp//鼠标滚轮缩放BOOL CScaleD2DView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt){    // TODO: Add your message handler code here and/or call default    double m_dScale = g_ScreenPara.zoomoffset.dZoom;    m_dScale += 0.1 * zDelta/ 120;    if(m_dScale <= 0.2)      {           m_dScale = 0.2;             }             if(m_dScale >= 2.0)      {        m_dScale = 2.0;     }    g_ScreenPara.zoomoffset.dZoom = m_dScale;    SetScrollSizes(MM_TEXT, g_ScreenPara.GetZoomRange());    Invalidate();    return CScrollView::OnMouseWheel(nFlags, zDelta, pt);}

结果

结果图

参考

1.MFC+GDI简化坐标平移缩放
2.Direct2D+MFC学习笔记
3.Direct2D教程(外篇)环境配置

0 0
原创粉丝点击