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动画: [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; } //--------------------------------------------------------------------------- (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- C++ STL标准模板库
- net.sf.json.JSONException: There is a cycle in the hier
- Oracle用户权限
- c# 二分查找算法
- ruby-on-rails – 使用Rails和Paperclip的s3的简单Amazon I
- c# – 在即时窗口中查看log4net的调试消息
- E: 未发现软件包 install_flash_player_11_linux.x86_64.ta
- ruby-on-rails-3 – 在Heroku(Rails)上崩溃的Copycopter服务
- c# – 构造函数可以返回一个子类吗?
- cocos2d-x游戏开发(十五)游戏加载动画loading界面