我要以“标准化”值介于-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之间变化,所以我想我在这里一定做错了。
答案 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));
}
答案 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