
October 28th, 2010, 11:42 PM
#1
GDI+ Coordinates
By default, a GDI+ function like DrawLine uses a coordinate system where the origin is in the top left corner and the units are pixels.
So DrawLine(0, 0, 640, 480) would draw a diagonal line from the top left to the bottom right of a 640x480 screen. How do I set up a Graphics object so that the origin is in the center and both axes have a range of [1, 1]?

October 28th, 2010, 11:52 PM
#2
Re: GDI+ Coordinates
You don't, that's how graphical coordinates work. That's how they work everywhere in computers and you just get used to it. You can always perform a simple transform:
Code:
Point ToLogicalCartesian(Point graphical, int maxHeight)
{
return new Point(graphical.X, maxHeight  graphical.Y);
}
Of course, not sure why you would need to. As far as the 1,1 domain, bitmap coordinates are integers, so you can't really. Why in the world would you need to? You can always normalize your data as you see fit.

October 29th, 2010, 12:04 AM
#3
Re: GDI+ Coordinates
Well, actually, GDI+ functions take floating point coordinates.
Currently I'm using:
x' = x * (ScreenWidth / 2) + (ScreenWidth / 2)
y' = y * (ScreenHeigh / 2) + (ScreenHeight / 2)
to get the conversion, but I thought GDI+ had a better way of doing it, though a matrix or something.
I'm writing a software renderer, so I have to convert 3d points to 2d points on the screen, and in that scenario bitmap coordinates are not intuitive at all and [1, 1] are.

October 29th, 2010, 12:20 AM
#4
Re: GDI+ Coordinates
For instance I can take a Graphics object with a resolution of 640x480 and I can:
graphics.Transform = new Matrix(1, 0, 0, 1, Width / 2, Height / 2);
and from now on the Graphics' origin is in the center. I was hoping there was a way to also scale the coordinates using something similar to get [1, 1] without having to call a separate function.

October 29th, 2010, 12:28 AM
#5
Re: GDI+ Coordinates
There is the System.Drawing.Drawin2D.Matrix class, but I have never used it for much more than simple image transforms (rotation and color). I'm not sure if you could use it to suit your needs here, but it's something to look into.
BTW, the Drawing2D namesapce holds the more advanced GDI+ classes and functions.
EDIT: Hehe, I see you found that. Yeah, I can't be of much more help here, I have never done what you are attempting to do. Are you opposed to looking into the DirectX API? It may be better suited for what you are doing, but it of course comes with its own learning curve.

October 29th, 2010, 12:39 AM
#6
Re: GDI+ Coordinates
This isn't a serious project. The goal is to create a very simple renderer in C# using only GDI+ for drawing lines or filling in triangles, so no Direct3d this time.
At least using the Matrix transformation simplifies things a bit. Instead of:
x' = x * (ScreenWidth / 2) + (ScreenWidth / 2)
y' = y * (ScreenHeigh / 2) + (ScreenHeight / 2)
I can instead use:
x' = x * Width;
y' = y * Height;

October 30th, 2010, 09:39 AM
#7
Re: GDI+ Coordinates
You should be able to include a scale operation in the transform matrix.

February 21st, 2011, 11:17 AM
#8
Re: GDI+ Coordinates
This is how in Visual Basic.NET to get the Cartesian coordinates with Translate and Scale:
Dim graphicsObj As Graphics
' move the origin to the lower left (position it inside Picture Box = Picture Height + border from the top).
graphicsObj.TranslateTransform(0.0F, PictureHeight +20)
'In MSDN the following operation is called  reflect acros Xaxis (http://msdn.microsoft.com/enus/library/8667dchf.aspx)
graphicsObj.ScaleTransform(1, 1)
' Scales an element by the specified ScaleX and ScaleY amounts
' multiplying the transformation matrix by a diagonal matrix whose elements are (1,1).
Hope it will help.

February 22nd, 2011, 11:59 AM
#9
Re: GDI+ Coordinates
You make your conversion from NDC to screenspace before you use your DrawLine.
To map NDCs with a range of 1 to 1 to screen space, the following formula is generally used:
Using 800x600 as a sample resolution, where:
ScreenX(max) = 800
ScreenY(max) = 600
So…
ScreenX = NDC(X) * 400 + 400
And
ScreenY = NDC(Y) * 300 + 300
taken from http://www.extremetech.com/article2/...1155158,00.asp
Last edited by ruderudy; February 22nd, 2011 at 12:04 PM.
Posting Permissions
 You may not post new threads
 You may not post replies
 You may not post attachments
 You may not edit your posts

Forum Rules

Click Here to Expand Forum to Full Width
This a Codeguru.com survey!
OnDemand Webinars (sponsored)
