加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 根据当前鼠标位置缩放图形

发布时间:2020-12-15 22:31:05 所属栏目:百科 来源:网络整理
导读:我正在尝试根据鼠标的当前位置缩放绘图.现在我的onMouseWheel方法看起来像这样(基于 this StackOverflow answer): private void onMouseWheel(object sender,MouseEventArgs e) { if (e.Delta 0) { _scale *= 1.25f; _translateY = e.Y - 1.25f * (e.Y - _t
我正在尝试根据鼠标的当前位置缩放绘图.现在我的onMouseWheel方法看起来像这样(基于 this StackOverflow answer):

private void onMouseWheel(object sender,MouseEventArgs e)
    {
        if (e.Delta > 0)
        {
            _scale *= 1.25f;
            _translateY = e.Y - 1.25f * (e.Y - _translateY);
            _translateX = e.X - 1.25f * (e.X - _translateX);
        }
        else
        {
            _scale /= 1.25f;
            _translateY = e.Y - 0.8f * (e.Y - _translateY);
            _translateX = e.X - 0.8f * (e.X - _translateX);
        }
        this.Invalidate();
    }

_scale,_translateX和_translateY是成员变量.

我正在缩放图形,翻译它,然后绘制这样的线条:

protected override void OnPaint(PaintEventArgs e)
    {
        g.ScaleTransform(_scale,_scale);
        g.TranslateTransform(_translateX,_translateY);
        //draw lines here
    }

This video显示当我尝试放大并缩小特定点时会发生什么.我究竟做错了什么?

这是用于测试目的的示例面板类中的代码:

class Display : Panel
{
    public Display()
    {
        this.MouseWheel += new MouseEventHandler(this.onMouseWheel);
    }

    private void onMouseWheel(object sender,MouseEventArgs e)
    {
        if (e.Delta > 0)
        {
            _scale *= 1.25f;
            _translateY = e.Y - 1.25f * (e.Y - _translateY);
            _translateX = e.X - 1.25f * (e.X - _translateX);
        }
        else
        {
            _scale /= 1.25f;
            _translateY = e.Y - 0.8f * (e.Y - _translateY);
            _translateX = e.X - 0.8f * (e.X - _translateX);
        }
        this.Invalidate();
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        g.ScaleTransform(_scale,_translateY);

        Pen pen = new Pen(Color.Red);
        g.FillEllipse(pen.Brush,50,10,10);
    }
}

解决方法

懒得让方程式正确(而且很可能会犯同样的错误……我不知道它是否仅仅是我,但确切地说,这些简单的东西我无法处理并让我发疯).相反,我正在处理如下的这类任务(它从错误中更加安全):

>在屏幕和世界坐标之间创建变换功能

因此,您的鼠标位置在屏幕坐标中,渲染的东西在世界坐标中.因为这只是2D,所以很容易. make函数在这两者之间转换.你的世界屏幕转换(如果我不忽视某些东西)是这样的:

g.ScaleTransform(_scale,_scale);
g.TranslateTransform(_translateX,_translateY);

所以:

screen_x=(world_x*_scale)+_translateX;
screen_y=(world_y*_scale)+_translateY;

所以相反:

world_x=(screen_x-_translateX)/_scale;
world_y=(screen_y-_translateY)/_scale;

>改变缩放/比例

我们的想法是,在缩放/缩放后,鼠标位置应保持与以前相同的世界坐标.所以记住改变之前鼠标的世界坐标.然后从中计算出更改后的屏幕位置和转换后的差异.

这里简单的C例子:

?

double x0=0.0,y0=0.0,zoom=1.0,mx,my;
//---------------------------------------------------------------------------
void scr2obj(double &ox,double &oy,double sx,double sy)
    {
    ox=(sx-x0)/zoom;
    oy=(sy-y0)/zoom;
    }
//---------------------------------------------------------------------------
void obj2scr(double &sx,double &sy,double ox,double oy)
    {
    sx=x0+(ox*zoom);
    sy=y0+(oy*zoom);
    }
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseWheelDown(TObject *Sender,TShiftState Shift,TPoint &MousePos,bool &Handled)
    {
    double mx0,my0;
    scr2obj(mx0,my0,my);
    zoom/=1.25; // zoom out
    obj2scr(mx0,mx0,my0);
    x0+=mx-mx0;
    y0+=my-my0;
    _redraw=true;
    }
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseWheelUp(TObject *Sender,my);
    zoom*=1.25; // zoom in
    obj2scr(mx0,my0);
    x0+=mx-mx0;
    y0+=my-my0;
    _redraw=true;
    }
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseMove(TObject *Sender,int X,int Y)
    {
    mx=X; my=Y;
    }
//---------------------------------------------------------------------------

mx,我是屏幕坐标中的实际鼠标位置,x0,y0是平移,缩放是比例.

这里捕获了GIF动画:

example

[edit1]看起来你的gfx对象使用转发矩阵

这意味着转换的顺序是相反的,所以方程式改变了一点……这里你的例子在C中:

void scr2obj(double &ox,double sy) 
 { 
 // ox=(sx-x0)/zoom; 
 // oy=(sy-y0)/zoom; 
 ox=(sx/zoom)-x0; 
 oy=(sy/zoom)-y0; 
 } 
//--------------------------------------------------------------------------- 
void obj2scr(double &sx,double oy) 
 { 
 // sx=x0+(ox*zoom); 
 // sy=y0+(oy*zoom); 
 sx=(x0+ox)*zoom; 
 sy=(y0+oy)*zoom; 
 } 
//--------------------------------------------------------------------------- 
void __fastcall TForm1::FormMouseWheelDown(TObject *Sender,bool &Handled) 
 { 
 double mx0,my0; 
 scr2obj(mx0,my); 
 zoom/=1.25; // zoom out 
 obj2scr(mx0,my0); 
 // x0+=mx-mx0; 
 // y0+=my-my0; 
 x0+=(mx-mx0)/zoom; 
 y0+=(my-my0)/zoom; 
 _redraw=true; 
 } 
//--------------------------------------------------------------------------- 
void __fastcall TForm1::FormMouseWheelUp(TObject *Sender,my); 
 zoom*=1.25; // zoom in 
 obj2scr(mx0,my0); 
 // x0+=mx-mx0; 
 // y0+=my-my0; 
 x0+=(mx-mx0)/zoom; 
 y0+=(my-my0)/zoom; 
 _redraw=true; 
 } 
//---------------------------------------------------------------------------

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读