【问题标题】:Calculate correct cursor position with pan and zoom使用平移和缩放计算正确的光标位置
【发布时间】:2014-09-05 02:58:50
【问题描述】:

我已经在这个问题上纠结了大约一个小时。

我有一个支持平移和缩放的视口,平移是通过存储 X 和 Y 轴的偏移量来处理的。缩放只是一个从 0.2 到 14 的浮点数。

我的问题是我需要能够将东西放置在用户在视口中单击的位置,但是当我缩放和平移时,鼠标坐标不正确。我一直无法弄清楚如何正确计算鼠标坐标。

这是我目前所拥有的图片:http://i.imgur.com/WQSXKJ2.png

如您所见,鼠标原点始终位于视口组件的左上角。您可以在图像的左下角看到平移 X 和 Y 偏移以及缩放值。我还添加了一个相对于视口左上角的鼠标坐标示例。

现在由于在该图像中它当前放大了我放置的对象将被偏移。

感谢您的宝贵时间!

使用适合我的情况的解决方案进行编辑:

void Viewport_MouseClick(object sender, MouseEventArgs e){
    Point mousePosition = new Point((int)((e.X - Pan.X) / Zoom),
                                    (int)((e.Y - Pan.Y) / Zoom));
}

这会在考虑平移和缩放的同时计算正确的“屏幕空间”鼠标位置。 我通过玩 TaWs 的答案得到了这个解决方案。感谢您的帮助! :)

【问题讨论】:

  • 您使用的是哪个平台? WPF,Winform..??您正在使用什么控件以及如何实现缩放?
  • 这是一个winform,我的控件派生自“UserControl”类。缩放只是一个浮点数,它传递给“OnPaint”方法中的“ScaleTransform”方法。

标签: c# zooming mouse coordinates pan


【解决方案1】:

把你的图片放入PictureBox,然后计算鼠标的相对位置。那是

    double Pic_width = orginal_image_width/ pictureBox.width;
    double Pic_height = orginal_image_height/ pictureBox.height;
    var mouseArgs = (MouseEventArgs)e;
    int xpoint = Convert.ToInt16(mouseArgs.X * Pic_width);
    int ypoint = Convert.ToUInt16(mouseArgs.Y * Pic_height);

此代码将为您提供图像中光标的位置。

【讨论】:

    【解决方案2】:

    使用 TrackBar 进行缩放,另外两个用于偏移,这似乎可行:

    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();
    }
    

    我已经为 Paint 事件添加了代码,所以你可以看看你是否也是这样处理它的。

    【讨论】:

    • 感谢您的回答,但是当我在放大时计算鼠标位置时,我在视口中放置的对象得到了负偏移。我处理 Paint 方法的方式是使用“TranslateTransform(pan.X, pan.Y)”,然后使用“ScaleTransform(Zoom, Zoom)”。
    • 我只是通过玩你的例子才弄明白的。我所做的是从鼠标位置减去平移偏移,然后将结果除以缩放,如下所示:“(int)((eX - Pan.X)/ Zoom)”和“(int)((eY - Pan.Y)/缩放)”。谢谢您的帮助! :)
    猜你喜欢
    • 2015-04-22
    • 1970-01-01
    • 2016-07-23
    • 2018-07-29
    • 1970-01-01
    • 1970-01-01
    • 2019-05-24
    • 1970-01-01
    • 2018-07-30
    相关资源
    最近更新 更多