Reputation: 508
How can I change transform the coordinates in a window from 0,0 topleft to 0,0 bottomleft.
I have tried various solutions with
SetMapMode(hdc,MM_TEXT);
,
SetViewportExtEx(hdc,0,-clientrect.bottom,NULL);
SetViewPortOrgEx(hdc,0,-clientrect.bottom,NULL);
SetWindowOrgEx(hdc,0,-clientrect.bottom,NULL);
SetWindowExtEx(hdc,0,-clientrect.bottom,NULL);
I have even tried google for a solution but to no prevail, so I turn to you the more experienced people on the internet.
The idea is I'm creating a custom control for linear interpolation and I could reverse the coordinate system by x,y in top right corner but I want it right. At the moment I get a reversed linear interpolation when I try to draw it as I cannot get the coords to be bottomleft.
I'm using win32 api, and I suspect I can skip the code as the screen coordinate system is almost identical on all systems, by that I mean 0,0 is "always" topleft on the screen if you are keeping it to standard 2d window and frames.
I really don't want a whole codesample to ease the typing pain for you guys, but I want some direction as it seems I cannot grasp the simple concept of flipping the coords in win32 api.
Thanks and a merry christmas
EDIT !
I would like to add my own answer to this question as I used simple math to reverse the view so to say.
If for an example I got the valuepair x,y (150,57) and another pair x,y (100,75) then I used this formulae height + (-1 * y)
and voila I get a proper cartesian coordinate field :) ofcourse in this example height is undefined variable but in my application its 200px in height.
Upvotes: 1
Views: 1510
Reputation: 133995
According to the documentation for SetViewportOrgEx, you generally want to use it or SetWindowOrgEx
, but not both. That said, you probably want the viewport origin to be (0, clientrect.bottom)
, not -clientrect.bottom
.
Setting transforms with GDI always made me crazy. I think you're better off using GDI+. With it, you can create a matrix that describes a translation of (0, clientRect.bottom)
, and a scaling of (1.0, -1.0)
. Then you can call SetWorldTransform
.
See the example at Using Coordinate Spaces and Transformations. For general information about transforms: Coordinate Spaces and Transformations.
Additional information:
I've not tried this with direct Windows API calls, but if I do the following in C# using the Graphics
class (which is a wrapper around GDI+), it works:
Graphics g = GetGraphics(); // gets a canvas to draw on
SetTranslateTransform(0, clientRect.Bottom);
SetScaleTransform(1.0f, -1.0f);
That puts the origin at the bottom left, with x
increasing to the right and y
increasing as you go up. If you use SetWorldTransform
as I suggested, the above will work for you.
If you have to use GDI, then you'll want to use SetViewportOrgEx(0, clientRect.bottom)
, and then set the scaling. I don't remember how to do scaling with the old GDI functions.
Note also that the documentation for SetViewportExtEx says:
When the following mapping modes are set, calls to the SetWindowExtEx and SetViewportExtEx functions are ignored.
- MM_HIENGLISH
- MM_HIMETRIC
- MM_LOENGLISH
- MM_LOMETRIC
- MM_TEXT
- MM_TWIPS
Upvotes: 1