Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
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.
Posted 2-Apr-13 5:14am
Edited 2-Apr-13 5:37am
_duDE_8K
v2
Rate this: bad
good
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) + 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.
  Permalink  
Comments
H.Brydon at 2-Apr-13 15:46pm
   
I hope you like all those +5's I've been handing out lately... :-)
nv3 at 2-Apr-13 15:50pm
   
I sure appreciate them, H.Brydon. As I do your contribution to this website.
Mobile.Instinct at 3-Apr-13 4:41am
   
Seriously thanks a lot for your answer and that special MulDiv trick. I never knew that existed.
nv3 at 3-Apr-13 4:46am
   
You're welcome.
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

  Permalink  
Comments
Mobile.Instinct at 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 at 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)



Advertise | Privacy | Mobile
Web03 | 2.8.1411022.1 | Last Updated 2 Apr 2013
Copyright © CodeProject, 1999-2014
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