CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com

1. Member +
Join Date
Aug 2008
Posts
902

## 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]?

2. Elite Member
Join Date
Jun 2008
Posts
2,477

## 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.

3. Member +
Join Date
Aug 2008
Posts
902

## 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.

4. Member +
Join Date
Aug 2008
Posts
902

## 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.

5. Elite Member
Join Date
Jun 2008
Posts
2,477

## 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.

6. Member +
Join Date
Aug 2008
Posts
902

## 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)

x' = x * Width;
y' = y * Height;

7. ## Re: GDI+ Coordinates

You should be able to include a scale operation in the transform matrix.

8. Junior Member
Join Date
Dec 2010
Location
Russia
Posts
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 X-axis (http://msdn.microsoft.com/en-us/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.

9. Junior Member
Join Date
Feb 2009
Posts
23

## 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 11:04 AM.

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•