From: Joseph M. Newcomer on 9 Feb 2010 15:03 See below... On Tue, 9 Feb 2010 07:00:11 -0800 (PST), Luigino <npuleio(a)rocketmail.com> wrote: >hi Joe, > >> Generally, a "grid" is in terms of the data's logical values, so if you wanted to draw a >> grid at y=100, you would simply draw the grid at y=100 and the coordinate transformations >> would take care of putting it inthe "right" place (+/- 1 pixel). But if the grid is just >> some reference grid which does not correlate to the data, then you draw it before setting >> your coordinate transformations. > >I followed your suggests about separating in subroutines to check what >was wrong... and using your application Viewport I tried to apply >32767 as hypotetical max logical range of values that could be >represented graphically from source to SetWindowExt's Y, then I tried >to vary SetWindowOrg's Y value to have the graphic represented with >origin at bottom right and I reached that value at 4988. **** What is the size of your rectangle? I guess I missed the origin-at-bottom-RIGHT part of it. If you want positive-X to move LEFT from the origin, then it would be SetWindowExt(-r.Width(), ymax); SetViewportExt(r.Width(), -r.Height()); SetWindowOrg(r.Width(), 0); SetViewportOrg(-r.Width(), 0); At least according to Viewport Explorer **** >Finally I settled manually in my application: > >dc.SetMapMode(MM_ANISOTROPIC); >dc.SetWindowOrg(rc.right, 4988); >dc.SetViewportOrg(0, 0); **** I note you are setting the origins before setting the mapping. Is there a reason for this? Note that origins are set in terms of logical coordinates, but in the code you show, you are setting the origin in terms of the logical coordinates of the unmapped coordinate system, then you remap the coordinate system, which of course renders the origins in terms of the new mapping. Change the order. **** >dc.SetWindowExt(rc.right, 32767); >dc.SetViewportExt(-rc.right, -rc.bottom); > >in this way I could get graphic "scaled" on the screen along >rc.Height(). >But I have still two questions: > >Let's suppose a day I pass a different max logical range value to >SetWindowExt's Y, what would be the formula to get its relative value >in device context units to assign to SetWindowOrg's Y coord? **** First, note that what you had done above is incorrect in terms of setting the origin, so before you do anything else, fix that problem. Next, why do you need to know the value in other than logical units (note: there is no such concept as "device context units". I don't even know what that means. There are two important concepts: logical coordinates, which are expressed in terms of the abstract value ranges you want to use, and there are device coordinates, which are always in terms of screen pixels. The device CONTEXT is what maps logical coordinates to physical coordinates. You care about these mappings if, for example, you are trying to correlate mouse position (which is in device coordinates) to a logical place on your drawing (which is in logical coordinates). The functions LPtoDP (Logical Points to Device Points) and DPtoLP (Device Points to Logical Points), which are methods of the CDC, are used for this. So, for example, suppose you wanted to draw a grid 20 pixels x 20 pixels (independent of any mapping, so the grid is essentially useless for most purposes that a graphical grid is usually used for). One way to do this is to draw the grid every 20 pixels before you SetMapMode, e.g., to draw it from the bottom up, do for(int y = r.bottom; y >= 0; y -= GRID_SPACING) { dc.MoveTo(0, y); dc.LineTo(r.right, y); } Alternatively, you could establish the mapping mode, and then do for(int y = 0; y < r.Height(); y += GRID_SPACING) { CPoint pt0(r.bottom + y, r.left); CPoint pt1(r.bottom + y, r.right); dc.DPtoLP(&pt0); dc.DPtoLP(&pt1); dc.MoveTo(pt0); dc.LineTo(pt1); } **** > >Since I assign the origin of the client screen to bottom-right corner, >in the array "logical" points as initial starting value I tried to >assign to POINT.Y = 0 but it wasn't working and the start line was >shown in the middle of the client screen, so I have to assign 4988 to >initial POINT.Y so it would be shown at the top of client screen. Is >there something wrong maybe to set initial start line at the >bottom?... **** Since you set the origin, in logical coordinates, before you set the mapping, it is all messed up. Fix that first before worrying about other problems. joe **** > >Thanks, >Ciao >Luigi Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Luigino on 9 Feb 2010 20:16 Hello Joe, > I guess I missed the origin-at-bottom-RIGHT part of it. > > If you want positive-X to move LEFT from the origin, then it would be > > SetWindowExt(-r.Width(), ymax); > SetViewportExt(r.Width(), -r.Height()); > SetWindowOrg(r.Width(), 0); > SetViewportOrg(-r.Width(), 0); > > At least according to Viewport Explorer Well my test to Viewport Explorer produced this result: http://img96.imageshack.us/img96/6986/fromviewportsetting3276.jpg As you can see those two arrows are at bottom right corner so the graphic should start from there so looking in the code of Viewport Explorer I supposed to start calling SetViewportOrg first. So basing from this Viewport result and supposing to test a range between 0 and 32767, I settled to test a result on the screen: the X POINT array settled to -27000 at the begin to have initial line at the bottom but looks like it's not really right since it should be 0 for Polyline to drawn the line at bottom since the origin is at the bottom right. In fact the result in normal state is this: http://img200.imageshack.us/img200/4012/normalstatewnidow.jpg and in maximized state is this: http://img59.imageshack.us/img59/9676/maximizedstatewindow.jpg where at maximized the line at bottom isn't precisely at the bottom. Even in both screenshots you can see a red line... this is produced doing: CPen qZeroPen( PS_SOLID, 2, RGB(255, 0, 0) ); /* red pen to check what's the 0 coordinate */ dc.SelectObject(&qZeroPen); dc.MoveTo(rc.left, 0); dc.LineTo(rc.right, 0); where that would mean being at the bottom since the origin it's supposed to be at bottom right corner. But I could have missed something... even if at least, as you see in the pictures, the scaling of the Polyline graphic is correct when maximized and normal state form... what do you think?..... Thanks Ciao Luigi
From: Luigino on 10 Feb 2010 03:18 Hi again Joe, On the other hand I tried to set your suggest about point origin then I tried to draw a red line at bottom, which it should supposed to with this code: void CMyDLL::PrepareDC(CDC & dc) { CRect rc; dc.GetClipBox(&rc); switch (iGraphType) { case GRAPH_BARS: { //dc.Rectangle() } break; case GRAPH_LINES: { ::SetGraphicsMode(dc, GM_COMPATIBLE); dc.SetMapMode(MM_ANISOTROPIC); dc.SetWindowExt(-rc.Width(), 32767); dc.SetViewportExt(rc.Width(), -rc.Height()); dc.SetWindowOrg(rc.Width(), 0); dc.SetViewportOrg(-rc.Width(), 0); //dc.SetWindowExt(rc.right, 32767); //dc.SetViewportExt(-rc.right, -rc.bottom); //dc.SetWindowOrg(rc.right, 4988); //dc.SetViewportOrg(0, 0); CPen qZeroPen( PS_SOLID, 2, RGB(255, 0, 0) ); / * red pen to check what's the 0 coordinate */ dc.SelectObject(&qZeroPen); dc.MoveTo(rc.left, rc.Height()); dc.LineTo(rc.right, rc.Height()); } break; default: break; } } but it doesn't even appear... tried also with rc.top and 0 (which should mean drawing the line at the top of the client rect) but nothing... And I'm creating the graphic control in the whole client rect of the CDialog test application: CRect rect; GetClientRect(&rect); CStatic MyStaticControl; MyControl.Create( this, &MyStaticControl, rect, MyStaticControl.GetDlgCtrlID() ); which would mean the graphic is drawn all inside the CDialog form.... that's weird... Any hint?... Thanks Ciao Luigi
From: Stephen Myers on 10 Feb 2010 09:32 Luigino wrote: > Hi again Joe, > > On the other hand I tried to set your suggest about point origin then > I tried to draw a red line at bottom, which it should supposed to with > this code: > > void CMyDLL::PrepareDC(CDC & dc) > { > CRect rc; > dc.GetClipBox(&rc); > > switch (iGraphType) > { > case GRAPH_BARS: > { > //dc.Rectangle() > } > break; > > case GRAPH_LINES: > { > ::SetGraphicsMode(dc, GM_COMPATIBLE); > dc.SetMapMode(MM_ANISOTROPIC); > dc.SetWindowExt(-rc.Width(), 32767); > dc.SetViewportExt(rc.Width(), -rc.Height()); > dc.SetWindowOrg(rc.Width(), 0); > dc.SetViewportOrg(-rc.Width(), 0); > > //dc.SetWindowExt(rc.right, 32767); > //dc.SetViewportExt(-rc.right, -rc.bottom); > //dc.SetWindowOrg(rc.right, 4988); > //dc.SetViewportOrg(0, 0); > > CPen qZeroPen( PS_SOLID, 2, RGB(255, 0, 0) ); / > * red pen to check what's the 0 coordinate */ > dc.SelectObject(&qZeroPen); > dc.MoveTo(rc.left, rc.Height()); > dc.LineTo(rc.right, > rc.Height()); > } > break; > > default: > break; > } > } > > but it doesn't even appear... tried also with rc.top and 0 (which > should mean drawing the line at the top of the client rect) but > nothing... > And I'm creating the graphic control in the whole client rect of the > CDialog test application: > > CRect rect; > GetClientRect(&rect); > CStatic MyStaticControl; > > MyControl.Create( this, &MyStaticControl, rect, > MyStaticControl.GetDlgCtrlID() ); > > which would mean the graphic is drawn all inside the CDialog form.... > > that's weird... > > Any hint?... > Thanks > Ciao > Luigi dc.SetWindowExt(-rc.Width(), 32767); rc.width() has nothing whatsoever to do with your data. How many samples have you taken? What is the LOGICAL width of the graph? You're still confusing pixel coordinates and logical coordinates. Steve
From: Luigino on 10 Feb 2010 12:06
Hello Steve, > dc.SetWindowExt(-rc.Width(), 32767); > rc.width() has nothing whatsoever to do with your data. How many > samples have you taken? What is the LOGICAL width of the graph? I set X logical extent as the same of rc.width() because I have an array with dimension of the desktop screen but I visualize on the screen only recent data from right to left because everytime I add a new element I execute a rotation of the array to add newest element at the end. In this way if I maximize the window which shows more data I can show more data. If datas goes like "outside the desktop" then they are considered like lost, that's the reason of the rotation... For this I have this objective to set the origin at bottom-right so if I have those array logical values example: { x=0 y=0; x=1 y=11423; x=2 y=3343; x=3 y=7543;...; x=122 y=432; x=123 y=27432 } Polyline would apply this logical array from right to left translating in device points obtaining a graphic that starts from the bottom-right corner showing an entire line at y=0 (in the bottom) then showing new elements in queue from right to left... Like if Polyline in that moment reads x=123 y=27432 this point would be represented at x=123 from right to left somewhere on Y between 0 and rc.Height() based on "translation extent"... Plus I was thinking about playing directly with logical values from source because since it's an array which at creation of the canvas is filled with zeros as Y and if I do a DPtoLP when I haven't mapped yet the canvas it would produce different value... Thanks Ciao Luigi |