自己在图片控制上的坐标 [英] Own coordinates on picture control

查看:97
本文介绍了自己在图片控制上的坐标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,



我正在尝试使用以下范围绘制2D图:X(0 - 3051)和Y(200,000 - 350,000)。将这些转换为与具有尺寸的图片控件相关的坐标的最佳方法是什么(顶部:192,左:11,底部:593,右:758)。

我一直试图获得我的范围正确,但从int到float的转换使它变得非常复杂。以下是我的代码。你能告诉我什么是错的吗?我怎样才能最好地解决这个问题?



 CDC * pDC =& argDc; 
CBrush * pOldBrush = pDC-> GetCurrentBrush();
CPen * pOldPen = pDC-> GetCurrentPen();

CRect rectClient;
m_GraphWindowCtrl.GetWindowRect(& rectClient);
ScreenToClient(& rectClient);

int GraphXRange = rectClient.Width();
int GraphYRange = rectClient.Height();

double ScreenXSeconds =( double )rectClient.Width()/ m_ScreenXMeters; // 3051
double ScreenYGain =( double )rectClient.Height()/ m_ScreenYMeters; // 350,000 - 200,000 = 150,000

画笔;
CBrush * pBrush;
brush.CreateSolidBrush(RGB( 0 255 0 ));
pBrush = pDC-> SelectObject(& brush);

CRect txtRectX,txtRectY;
CPen笔;
CPen * pPen;
pen.CreatePen(PS_SOLID | PS_COSMETIC, 1 ,RGB( 255 0 0 ));
pPen = pDC-> SelectObject(& pen);
pDC-> MoveTo(rectClient.TopLeft());





期待一些建议。我对逻辑到屏幕坐标理论感到很困惑。

解决方案

你实际上已经完成了自己的坐标计算所需的一切,假设你将windows视口保留在其中本机(文本)模式。两个因素 ScreenXSeconds ScreenYGain 是您必须将原始值相乘的因子。选择的名字不是我喜欢的,但这是另一个故事。为了我们的讨论,我们称之为 scaleX scaleY 。然后你会计算原点(rx,ry)的屏幕坐标:

  double  scaleX = rectClient .Width()/  3051 。; 
double scaleY = rectClient.Height()/ 150000 。;
...
int x = int (scaleX * rx)+ rectClient 。剩下;
int y = int (scaleY * ry)+ rectClient.top;



如果你想让y轴从下到上增长(就像大多数人一样)你需要稍微修改一下:

  int  y =  int (scaleY * -ry) + rectClient.bottom; 



而不是来回切换整数和双算术,还有一种纯整数方式:

  int  x = MulDiv(rx,rectClient.Width(), 3051  )+ rectClient.left; 
int y = MulDiv(-ry,rectClient.Height(), 150000 )+ rectClient 。底部;



如果速度是一个问题,后一版本可能是优选的。我们现代处理器中的浮点单元闪电般快速。但是:整数和浮点之间的转换以及特定的任何舍入都是一个相对较慢的操作。因此建议尽可能保持整数或浮点数并避免交叉。


您可以设置x和y坐标的尺寸并设置基点。所以你可以不经任何计算地绘制。





http://msdn.microsoft.com/en-us/library/windows/desktop/dd162980(v = vs.85)的.aspx [ ^ ]

http://msdn.microsoft.com/en-us/library/windows/desktop/dd145101(v = vs.85).aspx [ ^ ]

http://msdn.microsoft.com/en- us / library / windows / desktop / dd145100(v = vs.85).aspx [ ^ ]

Hello,

I am trying to draw a 2D graph using the following range : X( 0 - 3051) and Y( 200,000 - 350,000). What is the best way to convert these into coordinates relating to the picture control that has dimensions (top: 192, left: 11, bottom: 593, Right: 758).
I have been trying to get my range properly but the conversion from int to float is making it really complicated. Below is my code. Could you please let me know what is wrong and how can I best approach this?

CDC* pDC =  &argDc;
CBrush* pOldBrush = pDC->GetCurrentBrush();
CPen* pOldPen = pDC->GetCurrentPen();

CRect rectClient;
m_GraphWindowCtrl.GetWindowRect(&rectClient);
ScreenToClient(&rectClient);

int GraphXRange = rectClient.Width();
int GraphYRange = rectClient.Height();

double ScreenXSeconds = (double)rectClient.Width() / m_ScreenXMeters; // 3051
double ScreenYGain = (double)rectClient.Height() / m_ScreenYMeters; // 350,000 - 200,000 = 150,000

Brush brush;
CBrush* pBrush;
brush.CreateSolidBrush(RGB(0,255,0));
pBrush = pDC->SelectObject(&brush);

CRect txtRectX,txtRectY;
CPen pen;
CPen* pPen;
pen.CreatePen(PS_SOLID | PS_COSMETIC, 1, RGB(255,0,0));
pPen = pDC->SelectObject(&pen);
pDC->MoveTo(rectClient.TopLeft());



Looking forward to some suggestions. I am quite confused with the logical to screen coordinates theory.

解决方案

You did actually all that is necessary for your own coordinate calculation, assuming you leave the windows viewport in its native (text) mode. The two factors ScreenXSeconds and ScreenYGain are the factors with which you have to multiply the raw values. The names chosen are not to my liking, but that''s another story. For the sake of our discussion, lets call them scaleX and scaleY. Then you would calculate the screen coordinates for raw point (rx, ry):

double scaleX = rectClient.Width() / 3051.;
double scaleY = rectClient.Height() / 150000.;
...
int x = int (scaleX * rx) + rectClient.left;
int y = int (scaleY * ry) + rectClient.top;


If you want ot have the y-axis grow from bottom to top (as most people do) you need to modify that slightly:

int y = int (scaleY * -ry) + rectClient.bottom;


Instead of switching between integer and double arithmetic back and forth, there is also a pure integer way of doing this:

int x = MulDiv (rx, rectClient.Width(), 3051) + rectClient.left;
int y = MulDiv (-ry, rectClient.Height(), 150000) + rectClient.bottom;


If speed is an issue, the latter version is probably preferrable. The floating point unit in our modern processors is lightning fast. BUT: The conversion between integer and floating point and back and particular any rounding is a relatively slow operation. So one is well advised to stay in the integer or the floating point world whenever possible and avoid cross overs.


You can set dimension of x and y coordinate and set base point. So you can draw without any calculation.

See
http://msdn.microsoft.com/en-us/library/windows/desktop/dd162980(v=vs.85).aspx[^]
http://msdn.microsoft.com/en-us/library/windows/desktop/dd145101(v=vs.85).aspx[^]
http://msdn.microsoft.com/en-us/library/windows/desktop/dd145100(v=vs.85).aspx[^]


这篇关于自己在图片控制上的坐标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆