背景
问题由来
在参考1这篇文章里写了GDI下坐标缩放的情况,这里记录下再Direct2D绘图引擎下的缩放操作。
环境配置
参考文章2
几个概念
参考上一篇文章的说明配图
实现功能
1.所有图形初始缩放在默认视图框架内
2.(0,0)位置位于视图左下角
3.可以从屏幕坐标反推出原始数据坐标
4.使用Direct2D技术,在保持抗锯齿效果的同时,绘图效率和GDI差不多
思路及代码
流程图
计算等效初始坐标
1.遍历原始坐标获得XMAX,YMAX,XMIN,YMIN.
2.获得视窗访问WIDTH,HEIGHT.
3.计算初始缩放比率SCALE,计算方法为:
if(YMAX−YMINHEIGHT>XMAX−XMINWIDTH),SCALE=HEIGHTYMAX−YMIN
if(YMAX−YMINHEIGHT<XMAX−XMINWIDTH),SCALE=WIDTHXMAX−XMIN
同时得到绘图范围
RANGEX=(XMAX−XMIN)∗SCALE
RANGEY=(YMAX−YMIN)∗SCALE
4.计算等效初始坐标,计算方法为:
xnew=(xold−XMIN)∗SCALE
ynew=(yold−YMIN)∗−SCALE+RANGEY
其中乘以负的缩放系数并加上绘图范围的Y值是为了将坐标调整为y正向向上,左下角为(0,0)
5.反推原始数据
为了从屏幕坐标反推得到原始数据,必须传入视图滚动条位置信息ScrollPT及视图缩放系数Zoom(注意不是初始缩放系数SCALE)
计算方法为:
xold=xscreen+ScrollPT.xZoom∗SCALE+XMIN
yold=yscreen+ScrollPT.yZoom−RANGEY−SCALE+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);
}

本文介绍如何在Direct2D绘图引擎中实现坐标缩放功能,包括计算初始坐标、绘图范围、屏幕坐标到原始数据坐标的转换,并提供代码示例。
1764

被折叠的 条评论
为什么被折叠?



