Nat*_*ema 6 c# graphics zooming winforms
我正在尝试根据鼠标的当前位置缩放绘图。现在我的 onMouseWheel 方法看起来像这样(基于这个 StackOverflow 答案):
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();
}
Run Code Online (Sandbox Code Playgroud)
_scale, _translateX, 和_translateY是成员变量。
我正在缩放图形,翻译它,然后像这样绘制线条:
protected override void OnPaint(PaintEventArgs e)
{
g.ScaleTransform(_scale, _scale);
g.TranslateTransform(_translateX, _translateY);
//draw lines here
}
Run Code Online (Sandbox Code Playgroud)
该视频显示了当我尝试放大和缩小某个点时会发生什么。我究竟做错了什么?
这是用于测试目的的示例面板类中的代码:
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, _scale);
g.TranslateTransform(_translateX, _translateY);
Pen pen = new Pen(Color.Red);
g.FillEllipse(pen.Brush, 50, 50, 10, 10);
}
}
Run Code Online (Sandbox Code Playgroud)
太懒了,无法使方程式正确(并且很可能会犯与您类似的错误......我不知道这是否只是我,但正是这种简单的东西我无法处理并让我发疯)。相反,我按如下方式处理此类任务(这样更安全,不会出错):
创建屏幕坐标和世界坐标之间的变换函数
因此,您的鼠标位置位于屏幕坐标中,而渲染的内容位于世界坐标中。因为这只是2D,所以很容易。make函数在这两者之间进行转换。你的世界到屏幕的变换(如果我没有忽略某些事情)是这样的:
g.ScaleTransform(_scale, _scale);
g.TranslateTransform(_translateX, _translateY);
Run Code Online (Sandbox Code Playgroud)
所以:
screen_x=(world_x*_scale)+_translateX;
screen_y=(world_y*_scale)+_translateY;
Run Code Online (Sandbox Code Playgroud)
所以反过来:
world_x=(screen_x-_translateX)/_scale;
world_y=(screen_y-_translateY)/_scale;
Run Code Online (Sandbox Code Playgroud)改变缩放/比例
这个想法是,在缩放/缩放更改后,鼠标位置在世界坐标中应与以前保持相同。所以在改变之前记住鼠标的世界坐标。然后根据它计算更改后的屏幕位置并将差异放入翻译中。
这是简单的 C++ 示例:
g.ScaleTransform(_scale, _scale);
g.TranslateTransform(_translateX, _translateY);
Run Code Online (Sandbox Code Playgroud)
是mx,my屏幕坐标中的实际鼠标位置, 是x0,y0平移,zoom是比例。
这里捕获了这个的GIF动画:
[edit1] 看起来你的 gfx 对象使用了转播矩阵
这意味着转换的顺序颠倒了,因此方程发生了一些变化...这里是C++中的案例:
screen_x=(world_x*_scale)+_translateX;
screen_y=(world_y*_scale)+_translateY;
Run Code Online (Sandbox Code Playgroud)