热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

MFC+Direct2D简化坐标缩放

背景问题由来在参考1这篇文章里写了GDI下坐标缩放的情况,这里记录下再Direct2D绘图引擎下的缩放操作。环境配置参考文章2几个概念参考上一篇文章的说明配图实现

背景

问题由来

在参考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 vPT;
typedef D2D1_POINT_2F DPoint;
typedef std::vector 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教程(外篇)环境配置


推荐阅读
  • 在探讨C语言编程文本编辑器的最佳选择与专业推荐时,本文将引导读者构建一个基础的文本编辑器程序。该程序不仅能够打开并显示文本文件的内容及其路径,还集成了菜单和工具栏功能,为用户提供更加便捷的操作体验。通过本案例的学习,读者可以深入了解文本编辑器的核心实现机制。 ... [详细]
  • Spring – Bean Life Cycle
    Spring – Bean Life Cycle ... [详细]
  • Hadoop的文件操作位于包org.apache.hadoop.fs里面,能够进行新建、删除、修改等操作。比较重要的几个类:(1)Configurati ... [详细]
  • 如果应用程序经常播放密集、急促而又短暂的音效(如游戏音效)那么使用MediaPlayer显得有些不太适合了。因为MediaPlayer存在如下缺点:1)延时时间较长,且资源占用率高 ... [详细]
  • 在分析Android的Audio系统时,我们对mpAudioPolicy->get_input进行了详细探讨,发现其背后涉及的机制相当复杂。本文将详细介绍这一过程及其背后的实现细节。 ... [详细]
  • [转]doc,ppt,xls文件格式转PDF格式http:blog.csdn.netlee353086articledetails7920355确实好用。需要注意的是#import ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • 在尝试对 QQmlPropertyMap 类进行测试驱动开发时,发现其派生类中无法正常调用槽函数或 Q_INVOKABLE 方法。这可能是由于 QQmlPropertyMap 的内部实现机制导致的,需要进一步研究以找到解决方案。 ... [详细]
  • 如何将TS文件转换为M3U8直播流:HLS与M3U8格式详解
    在视频传输领域,MP4虽然常见,但在直播场景中直接使用MP4格式存在诸多问题。例如,MP4文件的头部信息(如ftyp、moov)较大,导致初始加载时间较长,影响用户体验。相比之下,HLS(HTTP Live Streaming)协议及其M3U8格式更具优势。HLS通过将视频切分成多个小片段,并生成一个M3U8播放列表文件,实现低延迟和高稳定性。本文详细介绍了如何将TS文件转换为M3U8直播流,包括技术原理和具体操作步骤,帮助读者更好地理解和应用这一技术。 ... [详细]
  • Python 序列图分割与可视化编程入门教程
    本文介绍了如何使用 Python 进行序列图的快速分割与可视化。通过一个实际案例,详细展示了从需求分析到代码实现的全过程。具体包括如何读取序列图数据、应用分割算法以及利用可视化库生成直观的图表,帮助非编程背景的用户也能轻松上手。 ... [详细]
  • 本文详细解析了 Android 系统启动过程中的核心文件 `init.c`,探讨了其在系统初始化阶段的关键作用。通过对 `init.c` 的源代码进行深入分析,揭示了其如何管理进程、解析配置文件以及执行系统启动脚本。此外,文章还介绍了 `init` 进程的生命周期及其与内核的交互方式,为开发者提供了深入了解 Android 启动机制的宝贵资料。 ... [详细]
  • 深入解析Android 4.4中的Fence机制及其应用
    在Android 4.4中,Fence机制是处理缓冲区交换和同步问题的关键技术。该机制广泛应用于生产者-消费者模式中,确保了不同组件之间高效、安全的数据传输。通过深入解析Fence机制的工作原理和应用场景,本文探讨了其在系统性能优化和资源管理中的重要作用。 ... [详细]
  • 本文介绍如何使用 Python 的 DOM 和 SAX 方法解析 XML 文件,并通过示例展示了如何动态创建数据库表和处理大量数据的实时插入。 ... [详细]
  • MySQL Decimal 类型的最大值解析及其在数据处理中的应用艺术
    在关系型数据库中,表的设计与SQL语句的编写对性能的影响至关重要,甚至可占到90%以上。本文将重点探讨MySQL中Decimal类型的最大值及其在数据处理中的应用技巧,通过实例分析和优化建议,帮助读者深入理解并掌握这一重要知识点。 ... [详细]
author-avatar
huanghunlaoren_619
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有