用于归一化0 - 1中任何数字的函数

Mar*_*zzo 11 javascript math performance normalization

我正在尝试创建一个函数,它接受一个数字并将其从最小和最大边界之间的0 - 1标准化.例如:

如果我想将值10标准化为5到15之间,我称之为:

val = 10; normalize(val, 5, 15); 返回0.5

将值0标准化为-10到5之间

val = 0; normalize(val, -10, 5); 返回0.666

这是我提出的功能:

function normalize(val, min, max){
  // Shift to positive to avoid issues when crossing the 0 line
  if(min < 0){
    max += 0 - min;
    val += 0 - min;
    min = 0;
  }
  // Shift values from 0 - max
  val = val - min;
  max = max - min;
  return Math.max(0, Math.min(1, val / max));
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:这是规范化一维值的最有效方法吗?我将以每帧60fps的速度调用此函数几千次,因此我希望尽可能优化它以减少计算负担.我已经找到了归一化公式,但我找到的只是二维或三维解.

小智 35

为什么不呢:

__CODE__

  • 非常好,谢谢!这似乎是最简单的方法。我用 if 语句使事情变得过于复杂。但是,我仍然想将值限制在 0 和 1 之间,所以我正在考虑做`return Math.max(0, Math.min(1, val-min / max-min))` (2认同)
  • @MarcoDelValle 只要 `val` 实际上介于 `min` 和 `max` 之间,结果将始终介于 0 和 1 之间。 (2认同)
  • @MarcoDelValle:不要忘记在 `(max-min)` 周围加上括号。 (2认同)

Nin*_*olz 10

使用Nathan Bertons对一些具有相同值minmax值的预配置函数的答案,您可以使用它.

function normalize(min, max) {
    var delta = max - min;
    return function (val) {
        return (val - min) / delta;
    };
}

console.log([5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15].map(normalize(5, 15)));
Run Code Online (Sandbox Code Playgroud)


And*_*nis 7

当我想用已知的最小值、最大值对两个范围之间的值进行归一化时,我更喜欢使用这个公式。您可以添加检查以约束输入,但如果将超出范围的值作为输入,这将正确计算与新范围的差异。

/**
 * Normalizes a value from one range (current) to another (new).
 *
 * @param  { Number } val    //the current value (part of the current range).
 * @param  { Number } minVal //the min value of the current value range.
 * @param  { Number } maxVal //the max value of the current value range.
 * @param  { Number } newMin //the min value of the new value range.
 * @param  { Number } newMax //the max value of the new value range.
 *
 * @returns { Number } the normalized value.
 */
const normalizeBetweenTwoRanges = (val, minVal, maxVal, newMin, newMax) => {
  return newMin + (val - minVal) * (newMax - newMin) / (maxVal - minVal);
};

const e = document.getElementById('result');
e.innerHTML = normalizeBetweenTwoRanges(10, 5, 15, 0, 1);
Run Code Online (Sandbox Code Playgroud)
<span id="result"></span>
Run Code Online (Sandbox Code Playgroud)


小智 5

Using Nathan Bertons's answer, you must validate if max-min is equal to zero, otherwise the return will be NaN:

function (val, max, min) { 
    if(max - min === 0) return 1; // or 0, it's up to you
    return (val - min) / (max - min); 
}
Run Code Online (Sandbox Code Playgroud)

and you can use a generalization to restrict the range of values in the dataset between any arbitrary points a and b using:

function (val, max, min) {
    if(max - min === 0) return a; // or b, it's up to you
    return a + (((val - min) * (b-a)) / (max - min));
}
Run Code Online (Sandbox Code Playgroud)