From: Joseph M. Newcomer on 8 Feb 2010 13:27 Oops. I missed that rect.bottom; eyes just slid right over it. You're right, it makes no sense whatsoever. Key is to keep the max of the array, either as elements are added, or by scanning it in the OnDraw/OnPaint handler. joe On Mon, 08 Feb 2010 11:35:32 -0600, Stephen Myers <""StephenMyers\"@discussions(a)microsoft.com"> wrote: >Luigino wrote: >> Hello Steve, >> >>> m_MemDC.SetMapMode(MM_ANISOTROPIC); >>> m_MemDC.SetWindowExt(m_MaxTime, m_nVMaxY); >>> m_MemDC.SetViewportOrg(0, rect.Height()); >>> m_MemDC.SetWindowOrg(0,0); >>> m_MemDC.SetViewportExt(rect.Width(),-rect.Height()); >>> m_MemDC.SelectObject(&m_VPen); >>> m_MemDC.Polyline(&m_VMinPts[0],(int)m_VMinPts.size()); >> >> in the array I'm not using time as X coordinates but just integers >> 1,2,3,4,...,n which are still consecutive integers as time values...so >> in the place of m_MaxTime I use current last X value in the array and >> in the place of m_nVMaxY I use rect.bottom since Y values in the array >> are actually random with this formula: >> >> myarray[i].y = (LONG)( (double)rand() / (RAND_MAX + 1) * (rect.bottom >> - 1) + 1 ); >> >> (the array is fixed size to the whole window resolution width where >> when I add new value at the last place I rotate before the array to >> shift-left it. >> The matter is setting SetWindowExt with last myarray[myarray.size() - >> 1].x and rect.bottom produces an assertion error. >> Using Newcomer's Viewport example I found on codeproject, i figured to >> set the origin at bottom right having axis going back to bottom-left >> and top-right it made me setting SetViewportOrg and SetWindowOrg >> respectively to 0,0 and rect.BottomRight() so it would start from >> bottom-right... and setting SetWindowExt to rect.Width() and >> rect.Height() didn't produced any assertion errors but doesn't >> repaints rescaled graphic (as you can see in the imageshack >> screenshots put before). >> >> Maybe I haven't got well in my mind about right settings of those >> SetWindowOrg, SetWindowExt, SetViewportOrg, SetViewportExt... >> >> Any suggest?... >> >> thanks >> ciao >> Luigi > >Luigi, > >Assume every reference to rect other than the scaling code is wrong. >Your data does not depend on the size of the window you are displaying >it in. Your data is in logical units, not screen units. rect does not >contain anything useful once the scaling has been completed. > >Try something like: >myarray[i].y = (LONG)( (double)rand() / (RAND_MAX + 1) * (m_nVMaxY) + 1); > >Steve Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Joseph M. Newcomer on 8 Feb 2010 13:35 In addition, there is no guarantee about how it is evaluated. Parentheses as given are insufficient. Instead of myarray[i].y = (LONG)( (double)rand() / (RAND_MAX + 1) * (rect.bottom - 1) + 1 ); it should have been written marray[i].y = (LONG)( ( ((double)rand()) / ((double)(RAND_MAX + 1)) ) + 0.5); because it is cpnfusing to depend on the operator priority. The +0.5 works correctly in this case only because the numbers are all positive; rounding with potential negative numbers is trickier. But it is possible that the rand() could have first been divided by (RAND_MAX + 1)*(rect.bottom - 1), and, as you observed, the rect.bottom must be eliminated. Note: I *think* I counted the parentheses correctly; my program editor does appropriate matching-parenthesis highlighting, but my newsreader does not. joe On Mon, 08 Feb 2010 11:37:10 -0600, Stephen Myers <""StephenMyers\"@discussions(a)microsoft.com"> wrote: >Joseph M. Newcomer wrote: >> See below... >> On Mon, 8 Feb 2010 02:13:34 -0800 (PST), Luigino <npuleio(a)rocketmail.com> wrote: >> >>> Hello Steve, >>> >>>> m_MemDC.SetMapMode(MM_ANISOTROPIC); >>>> m_MemDC.SetWindowExt(m_MaxTime, m_nVMaxY); >>>> m_MemDC.SetViewportOrg(0, rect.Height()); >>>> m_MemDC.SetWindowOrg(0,0); >>>> m_MemDC.SetViewportExt(rect.Width(),-rect.Height()); >>>> m_MemDC.SelectObject(&m_VPen); >>>> m_MemDC.Polyline(&m_VMinPts[0],(int)m_VMinPts.size()); >> **** >> >> I just used Viewport Explorer and verified these settings. >> >> Note that the order of setting the WindowExt before the ViewportExt is important, but you >> have that right. >> >> One thing I did when doing complex graphics was to put all the drawing in a *separate* >> subroutine. I would pass in a CDC & to it. So what I did was >> >> CPaintDC dc(this); >> #ifdef _DEBUG_GRAPHICS >> DoDrawing(dc); >> #else >> CDC memDC; >> ...create compatible DC and bitmap >> >> DoDrawing(memDC); >> ... transfer bitmap to surface >> #endif >> >> This allowed me to see if I was correctly drawing on the surface, and discover errors in >> my drawing logic (especially when I had Z-axis errors). Flickered like crazy, but easy to >> debug. Then I would remove the #define _DEBUG_GRAPHICS once I knew it worked. >> >> >> void CMyClass::DoDrawing(CDC & dc) >> { >> ... do drawing here >> } >> >> Because at this point, you don't actually know if the error is in the drawing or in the >> transfer of the bitmap to the surface, later. So this technique eliminates the >> uncertainty. >> **** >> >>> in the array I'm not using time as X coordinates but just integers >>> 1,2,3,4,...,n which are still consecutive integers as time values...so >>> in the place of m_MaxTime I use current last X value in the array and >>> in the place of m_nVMaxY I use rect.bottom since Y values in the array >>> are actually random with this formula: >>> >>> myarray[i].y = (LONG)( (double)rand() / (RAND_MAX + 1) * (rect.bottom >>> - 1) + 1 ); >>> >>> (the array is fixed size to the whole window resolution width where >>> when I add new value at the last place I rotate before the array to >>> shift-left it. >>> The matter is setting SetWindowExt with last myarray[myarray.size() - >>> 1].x and rect.bottom produces an assertion error. >> **** >> Really? I don't suppose you would tell us WHERE this error occurred? Did you check what >> routine it was in, what it was asserting for, and check the call to see why? Note that >> reporting "an" assertion error only wastes space; the proper report is to say "I got an >> assertion error in line XXXXX of file YYYYYY and I'm using VS version N" if you expect any >> help. Otherwise we have no idea what went wrong, and only Psychic Vibration Mode can be >> used to determine what has gone wrong. >> >> For all we know, your assertion error could be in the array access, which could certainly >> happen if the size was 0. >> **** >>> Using Newcomer's Viewport example I found on codeproject, i figured to >>> set the origin at bottom right having axis going back to bottom-left >>> and top-right it made me setting SetViewportOrg and SetWindowOrg >>> respectively to 0,0 and rect.BottomRight() so it would start from >>> bottom-right... and setting SetWindowExt to rect.Width() and >>> rect.Height() didn't produced any assertion errors but doesn't >>> repaints rescaled graphic (as you can see in the imageshack >>> screenshots put before). >> **** >> There's another little glitch you may need to be concerned with: in all versions of >> Windows < Vista, the DC for drawing has an area which encompasses the client area of the >> parent window (as far as I can tell, this was always a stupid design mistake, and they >> finally fixed it); therefore, if you want clipping, you may need to create a clipping >> region and select it into the DC if you get "spillover". >> **** >>> Maybe I haven't got well in my mind about right settings of those >>> SetWindowOrg, SetWindowExt, SetViewportOrg, SetViewportExt... >> **** >> One of the reasons I wrote the Viewport Explorer was because I always have trouble with >> it, unless I checked with a certain book where I wrote the explanation. But I've >> double-checked your settings, and they should scale the drawing to the rectangle, with the >> origin in the lower left corner >> joe >> **** >>> Any suggest?... >>> >>> 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 > >Joe, > >Thanks for making things like viewport explorer available. Hopefully, >it will speed things up for me next time I have to do this sort of thing. > >Steve 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 8 Feb 2010 20:34 Hello Joe and Stephen, obviously this: marray[i].y = (LONG)( ( ((double)rand()) / ((double)(RAND_MAX + 1)) ) + 0.5); was just a test to me using random numbers between a certain range like 1....32768, which I have to represent them on the screen between top and bottom canvas client where it has regular their rect dimensions. Let's suppose a day I'll give to the graphic values that are from a certain source, so I have already a property which to assign range value (logical units) that could be 1...1000000. Like, as we both know, SetViewportExt should be represent the drawn viewable range, indeed SetWindowExt should do something like the work to tell the device context to "translate" someway the logical value given to viewable representation... Plus there's the grid also to "preserve" from resizing which looks like changed when resized window... Wonder if there's a way to draw then avoiding to change their offset and stuff... Luigi
From: Joseph M. Newcomer on 9 Feb 2010 09:13 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. joe On Mon, 8 Feb 2010 17:34:43 -0800 (PST), Luigino <npuleio(a)rocketmail.com> wrote: >Hello Joe and Stephen, > >obviously this: > >marray[i].y = (LONG)( ( ((double)rand()) / ((double)(RAND_MAX + 1)) ) >+ 0.5); > >was just a test to me using random numbers between a certain range >like 1....32768, which I have to represent them on the screen between >top and bottom canvas client where it has regular their rect >dimensions. >Let's suppose a day I'll give to the graphic values that are from a >certain source, so I have already a property which to assign range >value (logical units) that could be 1...1000000. >Like, as we both know, SetViewportExt should be represent the drawn >viewable range, indeed SetWindowExt should do something like the work >to tell the device context to "translate" someway the logical value >given to viewable representation... > >Plus there's the grid also to "preserve" from resizing which looks >like changed when resized window... > >Wonder if there's a way to draw then avoiding to change their offset >and stuff... > >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 10:00
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. Finally I settled manually in my application: dc.SetMapMode(MM_ANISOTROPIC); dc.SetWindowOrg(rc.right, 4988); dc.SetViewportOrg(0, 0); 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? 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?... Thanks, Ciao Luigi |