Click here to Skip to main content
13,410,869 members (32,343 online)
Rate this:
Please Sign up or sign in to vote.

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;

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;
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);

Looking forward to some suggestions. I am quite confused with the logical to screen coordinates theory.
Posted 2-Apr-13 5:14am
Updated 2-Apr-13 5:37am
Rate this: bad
Please Sign up or sign in to vote.

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):
double scaleX = rectClient.Width() / 3051.;
double scaleY = rectClient.Height() / 150000.;
int x = int (scaleX * rx) + rectClient.left;
int y = int (scaleY * ry) +;

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.
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.
Rate this: bad
Please Sign up or sign in to vote.

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.

Style-7 2-Apr-13 12:00pm
Use this cool book, see chapter 5 The GDI Mapping Mode with examples,%20Charles%20Petzold,%205Th%20Ed).pdf

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

  Print Answers RSS
Top Experts
Last 24hrsThis month

Advertise | Privacy |
Web02 | 2.8.180225.1 | Last Updated 2 Apr 2013
Copyright © CodeProject, 1999-2018
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100