缩放因子

本文关键字:缩放 | 更新日期: 2023-09-27 18:13:41

我正在使用滚轮放大和缩小对象,使用以下方法:

void OnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
    lastMousePositionOnTarget = Mouse.GetPosition(grid);
    double max = 255;
    double min = .005;
    var deltaScale = Math.Max(Math.Log(scaleTransform.ScaleX), double.Epsilon);
    var delta = e.Delta > 0 ? Math.Max(e.Delta * deltaScale, .5) : Math.Min(e.Delta * deltaScale, -.5);
    double newScale = Math.Max(Math.Min((delta / 250d) + scaleTransform.ScaleX, max), min);
    scaleTransform.ScaleX = newScale;
    scaleTransform.ScaleY = newScale;
    System.Diagnostics.Debug.WriteLine(newScale);
    e.Handled = true;
}

我想让它在接近最大值时更慢地缩放,当数字接近最小值时更快地缩放。我目前有一些作品,但不是很好。我要怎么做才能达到我的目的?

缩放因子

假设我理解正确,您希望deltaScale在放大时较大,但在缩小时较小。因此,您可以在近距离时快速变焦,在远距离时缓慢变焦。

如果scaletransform.ScaleX随着你的放大而变小,尝试这样做:

var deltaScale = Math.Max(K * 1/(scaleTransform.ScaleX), double.Epsilon);

其中K只是一个常量,你可以随意摆弄,直到感觉合适为止。

如果scaletransform.ScaleX随着你的放大而变大,然后尝试像你的日志一样,系数大于1:

var deltaScale = Math.Max(5*Math.Log(scaleTransform.ScaleX), double.Epsilon);

这是我的最终答案,如果没有GEEF &帕维尔,非常感谢他们尽了最大的努力。

void OnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
    double max = 255;
    double min = .005;
    double scaler = 4;
    var deltaScale = Math.Min(Math.Max(scaler * scaleTransform.ScaleX / max, min),1) * Math.Sign(e.Delta);
    double newScale = Math.Max(Math.Min(deltaScale + scaleTransform.ScaleX, max), min);
    scaleTransform.ScaleX = newScale;
    scaleTransform.ScaleY = newScale;
    e.Handled = true;
}

我使用当前尺度与最大值的比率来获得斜率-并且不允许它变快(max 1)或太慢,min ==最小尺度。好的工作。

首先,我不会使用值e.Delta进行计算(当然需要符号)。这个值不是很可靠——在我的经验中,它接近于随机噪声。相反,使用常量值或一些计数器,比如在一行中调用了多少次放大,在一行中调用了多少次缩小。

所以我的第一次尝试(常量值)看起来像这样。

void OnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
    lastMousePositionOnTarget = Mouse.GetPosition(grid);
    double max = 255;
    double min = .005;
    var deltaScale = Math.Max(Math.Log(scaleTransform.ScaleX), double.Epsilon);
    var delta = e.Delta > 0 ? Math.Max(1 * deltaScale, .5) : Math.Min(1 * deltaScale, -.5);
    double newScale = Math.Max(Math.Min((delta / 250d) + scaleTransform.ScaleX, max), min);
    scaleTransform.ScaleX = newScale;
    scaleTransform.ScaleY = newScale;
    System.Diagnostics.Debug.WriteLine(newScale);
    e.Handled = true;
}

带有计数器的版本看起来像这样。

private double counter=0;
private bool isZoomIn=true;
void OnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
    lastMousePositionOnTarget = Mouse.GetPosition(grid);
    if( (e.Delta > 0 && isZoomIn) ||  (e.Delta < 0 && !isZoomIn))
               IncreaseCounter(counter);//is another one in a row
    else
               counter=1;
    isZoomIn = e.Delta > 0;//we set this flag for next time
    double max = 255;
    double min = .005;
    var deltaScale = Math.Max(Math.Log(scaleTransform.ScaleX), double.Epsilon);
    var delta = e.Delta > 0 ? Math.Max(counter * deltaScale, .5) : Math.Min(counter * deltaScale, -.5);
    double newScale = Math.Max(Math.Min((delta / 250d) + scaleTransform.ScaleX, max), min);
    scaleTransform.ScaleX = newScale;
    scaleTransform.ScaleY = newScale;
    System.Diagnostics.Debug.WriteLine(newScale);
    e.Handled = true;
}

请注意,我使用了伪函数IncreaceCounter而不是递增,因为您可能需要其他东西而不仅仅是线性递增。