Search code examples
c#monotranslategtk#cairo

mono c# CairoHelper.Translate


using Cairo;

I have drawn a rectangle inside a bigger rectangle witch is inside a drawing area.

I have managed to attach a event to the Drawing area witch is a object I have extended from it

this.AddEvents ((int) EventMask.ButtonPressMask);

this.ButtonPressEvent += delegate(object o, ButtonPressEventArgs args) {
    hasInterface(args.Event.X, args.Event.Y);

    Console.WriteLine("Button Pressed " + args.Event.X + ", " + args.Event.Y);
};

I'm dynamically drawing the squares using:

cr.Translate(width/2, height/2);

cr.Rectangle((pX + (i * tmp)) , pY, boxsize, boxsize);      

private void recordPosition(double x, double y)
{
    x = x*2;
    y = y*2;
    boxCoordinates.Add( new double[,]
        { 
            {x, y}
        }
    ); // store coords
}


List<double,double> boxCoordinates

So for the inside of the drawing area the square is drawn at x=0, y=0 from the "outside" point of view it's in x=90, y=45; the width = 180 , height = 100 I was using translate (since half of this is copied ) of the size/2 so this means that the drawing area was doing a resize of the square, to solve this issue I was saving the position's multiplying it by 2, but this is not working has I'm getting "hits" outside of the rectangle drawn.

What is the best way to do this? I mean to translate the X Y positions from the window to the drawing area, I saw this was possible in other languages but not sure how to do it in C# and the drawing area from mono.

Thanks for any help.


Solution

  • I've done this a few times in C w SDL and C# with Cairo, basically, you want to be able to convert the bounding box of each of your rectangles to and from the coordinates you are using for rendering on the cairo canvas.

    For each of your rectangles, you'll have the location you of your rectangles in thier own world. I like to call these the "world coordinates" and their "screen coordinates" (which map to where your mouse will be).

    You can store the world coordinates of each box and then translate them to screen ones for each frame you render.

    public class Shape {
      public Point WorldLoc { get; set; }
    }
    

    You would do all your physics (if you have any) on the WorldLoc values. When you come to render, You want to be able to convert your WorldLoc to ScreenLoc.

    public class Scene {
      public double Zoom;
      public Point Offset;
    
      public Point WorldToScreen( Point world ){
        var p = new Point();
        p.x = (world.x - Offset.x) * Zoom;
        p.y = (world.y - Offset.y) * Zoom;
        return p;
      }
    } 
    

    Each time you render somthing in this Scene, you'll use WorldToScreen() to get the screen coordinates. You can then use the same thing to work out if your mouse is in the screen box of a world box.