C# 缩放比例缩放因子

C# 缩放比例缩放因子,c#,math,C#,Math,我使用滚轮通过以下方法放大和缩小对象: void OnPreviewMouseWheel(object sender, MouseWheelEventArgs e) { lastMousePositionOnTarget = Mouse.GetPosition(grid); double max = 255; double min = .005; var deltaScale = Math.Max(Math.Log(scaleTransform.ScaleX)

我使用滚轮通过以下方法放大和缩小对象:

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

假设我理解正确,您希望您的
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);

首先,我不会使用值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;
}
带有计数器的版本看起来像这样

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;
}
专用双计数器=0;
private bool isZoomIn=true;
void OnPreviewMouseWheel(对象发送器、MouseWheelEventArgs e)
{
lastMousePositionOnTarget=Mouse.GetPosition(网格);
if((e.Delta>0&&isZoomIn)| |(e.Delta<0&&isZoomIn))
IncreaseCounter(counter);//是一行中的另一个
其他的
计数器=1;
isZoomIn=e.Delta>0;//我们为下次设置此标志
双倍最大值=255;
双最小值=.005;
var deltaScale=Math.Max(Math.Log(scaleTransform.ScaleX),double.Epsilon);
var delta=e.delta>0?数学最大值(计数器*deltaScale,.5):数学最小值(计数器*deltaScale,.5);
double newScale=Math.Max(Math.Min((delta/250d)+scaleTransform.ScaleX,Max),Min);
scaleTransform.ScaleX=新闻缩放;
scaleTransform.ScaleY=新闻缩放;
系统.诊断.调试.写线(newScale);
e、 已处理=正确;
}

请注意,我使用了伪函数incremaceCounter而不是incrementaion,因为您可能需要的不仅仅是线性增加。

首先,我不会使用值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;
}
带有计数器的版本看起来像这样

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;
}
专用双计数器=0;
private bool isZoomIn=true;
void OnPreviewMouseWheel(对象发送器、MouseWheelEventArgs e)
{
lastMousePositionOnTarget=Mouse.GetPosition(网格);
if((e.Delta>0&&isZoomIn)| |(e.Delta<0&&isZoomIn))
IncreaseCounter(counter);//是一行中的另一个
其他的
计数器=1;
isZoomIn=e.Delta>0;//我们为下次设置此标志
双倍最大值=255;
双最小值=.005;
var deltaScale=Math.Max(Math.Log(scaleTransform.ScaleX),double.Epsilon);
var delta=e.delta>0?数学最大值(计数器*deltaScale,.5):数学最小值(计数器*deltaScale,.5);
double newScale=Math.Max(Math.Min((delta/250d)+scaleTransform.ScaleX,Max),Min);
scaleTransform.ScaleX=新闻缩放;
scaleTransform.ScaleY=新闻缩放;
系统.诊断.调试.写线(newScale);
e、 已处理=正确;
}

请注意,我使用了伪函数递增计数器而不是递增计数器,因为您可能需要的不仅仅是线性递增。

这是我的最终答案,如果没有GEEF&Pawel,我将无法得出它。非常感谢他们尽了最大努力

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==最小比例。工作正常。

这是我的最终答案,如果没有GEEF&Pawel的话,我是不会想出这个答案的。非常感谢他们尽了最大的努力

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==最小比例。工作正常。

为便于使用/阅读,请预先计算刻度/大小,然后让鼠标滚轮调整索引@GEEF在计算数值方面是正确的。为了便于使用/阅读,请预先计算刻度/大小,并让鼠标滚轮调整索引@GEEF在计算数值方面是正确的。在我的测试案例中,e.Delta一直是一个常数120或-120。但是你的回答让我意识到这在所有计算机上并不总是一样的。所以我会慎重考虑的。至于计数器,我想避免这些-我应该能够做一些类型的等式,知道根据当前的比例我被放大了多远。X.我也在考虑同样的增量,使用常数和增量方向是最好的选择。在我的测试案例中,e.增量一直是一个常数120或-120。但是你的回答让我意识到这在所有计算机上并不总是一样的。所以我会慎重考虑的。我要走多远就走多远