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