CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    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. #2
    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. #3
    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. #4
    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. #5
    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. #6
    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)

    I can instead use:

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

  7. #7
    Join Date
    Apr 2004
    Location
    England, Europe
    Posts
    2,492

    Re: GDI+ Coordinates

    You should be able to include a scale operation in the transform matrix.
    My hobby projects:
    www.rclsoftware.org.uk

  8. #8
    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. #9
    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 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
  •  





Click Here to Expand Forum to Full Width

Featured