将值标准化为-1和1之间的范围

时间:2018-12-09 21:46:08

标签: c# math

我要以“标准化”值介于-1和1(包括带小数位的数字,例如0.0129)之间的方式处理操纵杆值。

具体地说,我正在处理Wiimote控制器棒的输入。

X轴的范围是35到228,Y轴的范围是27到220。

两者的中心都是128。

现在,我要使它成为X轴上的值35会导致-1,值128会导致0,而值228会导致1。

有特殊的处理方法吗?

我能想到的最好的方法是:

public float[] GetStickNormalizedDataXY() 
{
    float[] ret = new float[2];

    ret[0] = _stick[0];
    ret[0] -= 35;
    ret[1] = stick[1];
    ret[1] -= 27;

    for (int x = 0; x < 2; x++)
    {
        ret[x] /= 193f;
    }

    return ret;
}

但是我的结果仅在0到1之间变化,所以我想我在这里一定做错了。

2 个答案:

答案 0 :(得分:3)

这应该可以解决问题:

float[] NormalizeStickData(float[] stickData)
{
    return new[]
        { 
            Normalize(stickData[0], 35, 228, 128, -1, 1, 0),
            Normalize(stickData[1], 27, 220, 128, -1, 1, 0)
        };
}

float Normalize(float value, float oldMin, float oldMax, float oldMid, float newMin, float newMax, float newMid)
{
    if (value < oldMid)
        return Interpolate(value, oldMin, oldMid, newMin, newMid);
    else if (value > oldMid)
        return Interpolate(value, oldMid, oldMax, newMid, newMax);
    else
        return newMid;
}

float Interpolate(float value, float oldMin, float oldMax, float newMin, float newMax)
{
    return (float)(newMin + (newMax - newMin)*(value - oldMin)/(oldMax - oldMin));
}

Example

答案 1 :(得分:2)

如果要制作一个很好的平滑函数,使其在 3 个特定输入值下具有特定输出值,那么最简单的方法是使用二次多项式。这意味着形式为out = Ax ^ 2 + Bx + C,其中out是输出,x是输入。插入(x,out)=(35,-1),(128、0)和(228,1)得到3个方程,并求解A,B和C以得到x轴映射函数。

如果您想用一种更直观的方法来完成完全相同的事情,则可以在两个更简单的线性函数之间进行插值,如下所示:

user_id
category
view_hour