3

目前我有一个控件,我需要添加工具以应用各种敏锐度(或灵敏度)。这个问题最好用一张图来说明:

图 http://img87.imageshack.us/img87/7886/control.png

如您所见,我的 X 轴和 Y 轴都具有 100 的任意限制 - 这足以解释此解释。目前,我的控件是红线(线性行为),但我想添加其他 3 条曲线(或更多)的能力,即如果控件更敏感,则设置将忽略线性设置并选择一个三行中。起点永远是 0,终点永远是 100。

我知道指数太陡峭,但似乎无法找到前进的方向。请问有什么建议吗?

4

6 回答 6

3

您说明的曲线看起来很像伽马校正曲线。那里的想法是范围的最小值和最大值与输入保持相同,但中间像您在图表中一样弯曲(我可能会注意到这不是您从余弦实现中得到的圆弧)。

从图形上看,它看起来像这样:

替代文字
(来源:wikimedia.org

所以,以此为灵感,这就是数学......

如果您的 x 值介于 0 到 1 之间,则该函数相当简单:

y = f(x, gamma) = x ^ gamma

添加一个 xmax 值进行缩放(即 x = 0 到 100),函数变为:

y = f(x, gamma) = ((x / xmax) ^ gamma) * xmax

或者:

y = f(x, gamma) = (x ^ gamma) / (xmax ^ (gamma - 1))

如果要添加非零 xmin,可以更进一步。

当 gamma 为 1 时,该线始终是完全线性的 (y = x)。如果 x 小于 1,则曲线向上弯曲。如果 x 大于 1,则曲线向下弯曲。gamma 的倒数会将值转换回原始值 (x = f(y, 1/g) = f(f(x, g), 1/g)。

只需根据自己的口味和应用需求调整 gamma 的值即可。由于您希望为用户提供多个“灵敏度增强”选项,因此您可能希望在线性范围内为用户提供选择,例如从 -4(最不敏感)到 0(无变化)到 4(最敏感) ),并使用幂函数缩放您的内部伽马值。换句话说,给用户选择 (-4, -3, -2, -1, 0, 1, 2, 3, 4),但将其转换为 (5.06, 3.38, 2.25, 1.50, 1.00 , 0.67, 0.44, 0.30, 0.20)。

在 C# 中编码可能看起来像这样:

public class SensitivityAdjuster {
    public SensitivityAdjuster() { }
    public SensitivityAdjuster(int level) {
        SetSensitivityLevel(level);
    }
    private double _Gamma = 1.0;
    public void SetSensitivityLevel(int level) {
        _Gamma = Math.Pow(1.5, level);
    }
    public double Adjust(double x) {
        return (Math.Pow((x / 100), _Gamma) * 100);
    }
}

要使用它,创建一个新的 SensitivityAdjuster,根据用户偏好设置灵敏度级别(使用构造函数或方法,-4 到 4 可能是合理的级别值)并调用 Adjust(x) 以获得调整后的输出值. 如果您想要更宽或更窄的合理级别范围,您可以在 SetSensitivityLevels 方法中减少或增加 1.5 的值。当然,100 代表您的最大 x 值。

于 2009-06-24T21:40:28.800 回答
1

我提出了一个简单的公式,(我相信)可以满足您的要求。为了有一个完整的“四分之一圈”,这是你的极端情况,你会使用(1-cos((x*pi)/(2*100)))*100.

我的建议是在 y=x 和 y=(1-cos((x*pi)/(2*100)))*100 之间取加权平均值。例如,要非常接近线性(99% 线性),请采用:

y = 0.99*x + 0.01*[(1-cos((x*pi)/(2*100)))*100]

或者更一般地说,假设线性水平是 L,并且它在区间 [0, 1] 内,您的公式将是:

y = L*x + (1-L)*[(1-cos((x*pi)/(2*100)))*100]

编辑:我改为cos(x/100)cos((x*pi)/(2*100))因为 cos 结果在 [1,0] 范围内 X 应该在 [0,pi/2] 范围内而不是 [0,1] 范围内,对于最初的错误,我深表歉意。

于 2009-06-24T20:37:53.280 回答
0

您可能正在寻找多项式插值之类的东西。二次/三次/四次插值应该为您提供问题中显示的各种曲线。您显示的三条曲线之间的差异可能仅通过调整系数(间接确定陡度)即可实现。

于 2009-06-24T19:32:28.980 回答
0

从 0 到 1的图表将y = x^px你想做的事情,因为你p从 1 (这将给出红线)向上变化。随着p增加,曲线将越来越“推入”。p不必是整数。

(你必须缩放以得到 0 到 100,但我相信你可以解决这个问题)

于 2009-06-24T19:43:34.403 回答
0

我投票支持 Rax Olgud 的总体想法,但有一处修改:

y = alpha * x + (1-alpha)*(f(x/100)*100)

替代文字 http://www4c.wolframalpha.com/Calculate/MSP/MSP4501967d41e1aga1b3i00004bdeci2b6be2a59b?MSPStoreType=image/gif&s=6

其中 f(0) = 0, f(1) = 1, f(x) 是超线性的,但我不知道这个“四分之一圆”的想法从何而来,也不知道为什么 1-cos(x) 会是一个不错的选择.

我建议 f(x) = x k其中 k = 2, 3, 4, 5,无论为 &alpha = 0 提供所需的陡度。选择 k 的值作为固定数字,然后改变 α 来选择你的特定曲线。

于 2009-06-24T20:57:59.573 回答
0

对于这样的问题,我经常会从曲线中获取几个点,然后通过曲线拟合程序将其扔掉。那里有很多。这是一个提供 7 天免费试用的产品。

通过尝试不同的模型,我学到了很多东西。通常你可以得到一个非常简单的表达式来接近你的曲线。

于 2009-06-24T22:52:52.057 回答