I've been messing around with this problem for about an hour now.
I have a viewport which supports panning and zooming, the panning is handled by storing an offset for the X and Y axis. The zoom is just a float going from 0.2 to 14.
My problem is that I need to be able to place stuff where the user clicks in the viewport but when I zoom and pan the mouse coordinates are not correct. I haven't been able to figure out how to properly calculate the mouse coordinates.
Here's an image showing what I have so far: https://i.sstatic.net/3hKHH.png
As you can see the mouse origin is always at the top-left of the viewport component. You can see the pan X and Y offset as well as the zoom value in the bottom-left corner of the image. I've also added an example of the mouse coordinates in relation to the top-left of the viewport.
Now since in that image it's currently zoomed in the objects I place will be offset.
Thank you for your time!
EDITED WITH SOLUTION THAT WORKS FOR MY CASE:
void Viewport_MouseClick(object sender, MouseEventArgs e){
Point mousePosition = new Point((int)((e.X - Pan.X) / Zoom),
(int)((e.Y - Pan.Y) / Zoom));
}
This calculates a correct "screen-space" mouse position whilst taking the pan and zoom into account. I got that solution by playing around with TaWs answer. Thank you for the help! :)
Using a TrackBar for the Zoom and two more for the offsets this seems to work:
private void panel1_Paint(object sender, PaintEventArgs e)
{
using (Bitmap bmp = new Bitmap(filename))
{
e.Graphics.ScaleTransform(zoom, zoom);
e.Graphics.DrawImage(bmp, trb_offsetX.Value, trb_offsetY.Value);
}
}
float zoom = 1f;
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
Point mouseLocation = e.Location;
Point imageLocation = new Point((int)((mouseLocation.X / zoom - trb_offsetX.Value)),
(int)((mouseLocation.Y / zoom - trb_offsetY.Value)));
st_mousePos.Text = " " + imageLocation.ToString();
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
zoom = trackBar1.Value;
panel1.Invalidate();
}
I have added the code for the Paint event, so you can see if that's the way your are handling it, too.