16,001,679 members
1.00/5 (1 vote)
See more:
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?

C++
```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.
Posted
Updated 2-Apr-13 4:37am
v2

## Solution 2

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):
C++
```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:
C++
```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:
C++
```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.

H.Brydon 2-Apr-13 15:46pm
I hope you like all those +5's I've been handing out lately... :-)
nv3 2-Apr-13 15:50pm
I sure appreciate them, H.Brydon. As I do your contribution to this website.
Mobile.Instinct 3-Apr-13 4:41am
Seriously thanks a lot for your answer and that special MulDiv trick. I never knew that existed.
nv3 3-Apr-13 4:46am
You're welcome.

## Solution 1

Mobile.Instinct 2-Apr-13 11:48am
Hello, could you please give an example on how could use it in my situation? It seems to be quite easy but I'm really struggling to get this bit working. Looking forward to your reply.

Thanks.
Style-7 2-Apr-13 12:00pm
Use this cool book, see chapter 5 The GDI Mapping Mode with examples
http://share.auditory.ru/2008/Dmitry.Boldyrev/Books/WinAPI/Programming%20Windows%20-%20Win32%20Api%20(Mspress,%20Charles%20Petzold,%205Th%20Ed).pdf

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Top Experts
Last 24hrsThis month
 Richard Deeming 80 merano99 40 Christian Graus 40 Dave Kreskowiak 15 Pete O'Hanlon 10
 OriginalGriff 631 Richard Deeming 320 Dave Kreskowiak 286 Pete O'Hanlon 270 CPallini 120

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900