Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 函数来规范化0-1之间的任何数字_Javascript_Performance_Math_Normalization - Fatal编程技术网

Javascript 函数来规范化0-1之间的任何数字

Javascript 函数来规范化0-1之间的任何数字,javascript,performance,math,normalization,Javascript,Performance,Math,Normalization,我试图创建一个函数,它接受一个数字,并在其最小和最大边界之间从0-1对其进行规格化。例如: 如果我想将5到15之间的值10标准化,我称之为: val=10;正常化(val,5,15)返回0.5 规范化介于-10和5之间的值0 val=0;正常化(val,-10,5)返回0.666 这就是我提出的功能: function normalize(val, min, max){ // Shift to positive to avoid issues when crossing the 0 line

我试图创建一个函数,它接受一个数字,并在其最小和最大边界之间从0-1对其进行规格化。例如:

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

val=10;正常化(val,5,15)返回0.5

规范化介于-10和5之间的值0

val=0;正常化(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));
}
函数正常化(val、min、max){
//切换为正值,以避免跨越0线时出现问题
如果(最小值<0){
最大+=0-min;
val+=0-min;
最小值=0;
}
//将值从0移动到最大值
val=val-min;
最大=最大-最小;
返回数学最大值(0,数学最小值(1,val/max));
}
我的问题是:这是规范化一维值的最有效方法吗?我将以每帧60fps的速度调用这个函数几千次,所以我希望尽可能优化它,以减少计算负担。我寻找过规范化公式,但我找到的都是二维或三维解。

为什么不只是:

function(val, max, min) { return (val - min) / (max - min); }
对于具有相同
min
max
值的某些值,使用带有预配置函数的“答案”,可以使用此选项

函数正常化(最小值、最大值){
var delta=最大-最小值;
返回函数(val){
返回值(val-min)/delta;
};
}
log([5,6,7,8,9,10,11,12,13,14,15].map(normalize(5,15))使用的答案,必须验证max-min是否等于零,否则返回值将为NaN:

function (val, max, min) { 
    if(max - min === 0) return 1; // or 0, it's up to you
    return (val - min) / (max - min); 
}
您可以使用a限制数据集中任意点a和b之间的值范围,使用:

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

我将完成Nina Scholz的答案,您可以使用下划线库查找数组的最小值和最大值,您可以按如下方式使用,或者创建自己的(简单循环的简单方法):

如果您使用的是nodeJS,则需要使用命令npm install underline安装下划线,并使用命令with安装下划线
var\uxAE=require('下划线/下划线')
或者您可以在html上导入库并在web上使用



    function min(arr) {
        if (!arr.length) return null;
        var minValue = arr[0];
        for (var item of arr) {
            if (item  maxValue) maxValue = item;
        }
        return maxValue;
    }

    var array = [1, 2, 3, 4, 5, 6, 7, 8, 9];

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

    function normalizeArray(array) {
        var minValue = min(array); //if you use underscore _.min(array)
        var maxValue = max(array);//if you use underscore _.max(array)
        return array.map(normalize(minValue, maxValue));
    }
    console.log(normalizeArray(array));


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

/**
*将值从一个范围(当前)规范化为另一个范围(新)。
*
*@param{Number}val//当前值(当前范围的一部分)。
*@param{Number}minVal//当前值范围的最小值。
*@param{Number}maxVal//当前值范围的最大值。
*@param{Number}newMin//新值范围的最小值。
*@param{Number}newMax//新值范围的最大值。
*
*@返回{Number}规范化值。
*/
常量normalizeBetweenTwoRanges=(val,minVal,maxVal,newMin,newMax)=>{
返回newMin+(val-minVal)*(newMax-newMin)/(maxVal-minVal);
};
const e=document.getElementById('result');
e、 innerHTML=normalizeBetweenTwoRanges(10,5,15,0,1)

如果您想要更动态的方法,可以指定最大范围,那么这就是这里的解决方案,在本例中,我们将在0到100的范围内对数据进行规范化

    let a = [500, 2000, 3000, 10000];

    function normalize(data, arr_max, arr_min, newMax){
        return data.map(d => {
            return newMax * ((d - arr_min)/(arr_max - arr_min))
        })
    }


console.log(normalize(a, 10000, 500, 100))
具有最大最小限制

函数正常化(最小值、最大值){
常数增量=最大-最小值;
返回val=>((valmax?max:val))-min)/delta;
}
log([-2,3,5,6,7,8,9,10,11,23].map(规范化(0,10));
// [
输出:[0, 0.3, 0.5, 0.6, 0.7, 0.8, 0.9, 1. 1. 1.
]

我看不出你为什么要单独处理负min,数组的min和max总是一样的吗?@redneb哇,你说得对!我是先发制人地这样做的,没有真正测试它。它不转换为>0@NinaScholz最小值和最大值会根据我调用它的位置而变化。有时它会是
-100,0
sometimes
-3781
等@MarcoDelValle所以只要去掉负min的特殊处理,你就可以开始了。太好了,谢谢!这似乎是最简单的方法。我用if语句过度复杂化了。但是,我仍然想将值钳制在0和1之间,所以我正在考虑执行
返回Math.max(0,Math.min(1,最小值/最大最小值))
@MarcoDelValle只要
val
实际上在
min
max
之间,结果总是在0和1之间。@Keiwan我知道。问题是
val
并不总是在
min
max
之间,所以我需要一种方法来防止它返回负数或任何上面的数字1@MarcoD埃尔瓦利:别忘了在
(max-min)
@Keiwan的周围加上括号,如果我想要-1之间的值,那么你会发现max函数:)函数max(arr){if(!arr.length)返回null;var maxValue=arr[0];for(arr的var项){if(项>maxValue)maxValue=item;}返回maxValue;}
max-min
如果它们有相同的值,那么它们将等于零,你不可能给出
max=5
min=5
。我觉得这只会使被接受的答案过于复杂。我从来没有要求数组映射,也没有要求乘以
newMax
值。只是要小心,因为这不支持负范围,这里有一个执行以下操作的实现:抱歉,它是在C#中。更简单:
返回Math.max(0,Math.min(1,val-min/max-min))
function normalize(min, max) {
   const delta = max - min;
   return val => ( (val < min? min: (val > max? max : val)) - min ) / delta;
}
console.log([-2,3,5, 6, 7, 8, 9, 10,11,23].map(normalize(0, 10)));
// [