5

Im making a graph program and im stuck at where I need to get mouse coordinates to equal graphic scale. With picturebox I use transform to scale my graphic:

RectangleF world = new RectangleF(wxmin, wymin, wwid, whgt);
        PointF[] device_points =
            {
                new PointF(0, PictureBox1.ClientSize.Height),
                new PointF(PictureBox1.ClientSize.Width, PictureBox1.ClientSize.Height),
                new PointF(0, 0),
            };
        Matrix transform = new Matrix(world, device_points);
        gr.Transform = transform;

enter image description here Im using MouseMove function. Is there a way to transform mouse coordinates? When I put my mouse on x=9 I need my mouse coordinate to be 9.

private void PictureBox1_MouseMove(object sender, MouseEventArgs e)
    {
        Console.WriteLine(e.X);
    }
Peter Duniho
  • 68,759
  • 7
  • 102
  • 136
WhizBoy
  • 225
  • 1
  • 10
  • 2
    Don't lose track of the *transform*. You'll like its Invert() method, handy to map the mouse coordinates back to graph coordinates. – Hans Passant May 19 '16 at 23:43

1 Answers1

3

As Hans' comment implies, you can use a second Matrix to accomplish this. You can obtain it either by copying the original Matrix and calling the copy's Invert() method, or you can create the new Matrix from scratch by reversing your input rectangles from the original.

IMHO inverting is easier, but it does mean you'll need to create the inverse matrix and store it somewhere. E.g.:

    Matrix transform = new Matrix(world, device_points);
    gr.Transform = transform;
    inverseTransform = transform.Clone();
    inverseTransform.Invert();

where inverseTransform is a field in your class rather than a local variable, so that your mouse-handling code can use it later.

If you must construct the Matrix later, you could do it like this:

RectangleF device = new RectangleF(new Point(), PictureBox1.ClientSize);
PointF[] world_points =
    {
        new PointF(wxmin, wymin + whgt),
        new PointF(wxmin + wwid, wymin + whgt),
        new PointF(wxmin, wymin),
    };
Matrix inverseTransform = new Matrix(device, world_points);

In either case, you'd simply use the Matrix.TransformPoints() method in your mouse-handling code to apply the inverse transform to the mouse coordinates to get back to your world coordinates.

Peter Duniho
  • 68,759
  • 7
  • 102
  • 136
  • I did this but it return the same X and Y values. `inverseTransform = transform.Clone(); inverseTransform.Invert(); List location = new List(); Point p = new Point(e.X, e.Y); location.Add(p); inverseTransform.TransformPoints(location.ToArray()); Console.WriteLine("location = " + location[0]);` – WhizBoy May 20 '16 at 08:33
  • 2
    Based on your comment here: The point values are transformed in-place. You created a new array to pass to the `TransformPoints()` method, but you pass it directly to the method instead of keeping a reference to it. So the method transforms the points, but you have no way to get the new values. Try `Point[] location = { new Point(e.X, e.Y) }; inverseTransform.TransformPoints(location);`. – Peter Duniho May 20 '16 at 15:30