From: Joseph M. Newcomer on
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
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
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
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
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