消除数组中的项目以达到固定长度 - JavaScript

Eliminate Items From Array To Reach Fixed Length - JavaScript

我正在尝试编写一个 JavaScript 函数来从数组中删除项目以达到定义的长度。该函数应该通过数组均匀地消除“间隙”。我需要这个函数来简化 canvas 绘图的多边形顶点。

它应该是这样工作的:

这是我想出的代码:

function simplify(array, vertices) {

  // Calculate gap size
  var gap = array.length - vertices;
  gap = Math.floor(array.length / gap);

  var count = 0;
  var result = [];

  // Fill a new array
  for (var i = 0; i < array.length; i++) {
    if (count == gap) {
      count = 0;
    } else {
      result.push(array[i]);
      count++;
    }
  }

  // Eliminate 1 item in the middle if length is odd
  if (result.length > vertices) {
    result.splice(Math.floor(result.length / 2), 1);
  }
  return result;
}

// This gives the wrong result depending on the length of the input!
// The result should be an array with the length of 3
console.log(simplify([
  { x: 10, y: 20 },
  { x: 30, y: 40 },
  { x: 40, y: 50 },
  { x: 50, y: 60 }
], 3))

然而,这似乎只是有时有效,问题可能出在数学上。什么算法可以实现这个或者我做错了什么?

如果您只想消除项目以将该数组剪切到所需的长度。使用 Array.splice() 函数。

例如,如果您的 desiredLength = 3。你有一个 array = [1,2,3,4,5].

array.splice(0,desiredLength).length == desiredLength应该是真的。

也许这会 help

假设您有一个长度为 n 的字符串,并且您希望它的长度为 m。您有 n-2 个元素可供选择,m-2 个元素可供选择用于您的新数组。现在,假设您当前选择了 i 个元素并传递了 j 个元素。如果 i/j < (m-2)/(n-2) 那么你落后了。你可能应该采取另一个元素。对于最大均匀选择,您真正想知道的是 (i+1)/(j+1) 或 i/(j+1) 是否更接近您的目标 (m-2)/(n-2 ).如果溢出不是问题,你可以做一点代数来弄清楚这是否等同于 (i+1)(n-2) - (j+1)( m-2) 大于或小于 (n-2)/2; more 意味着 i 更好(所以不要拿这个),而 less 意味着 i+1 更好。

我用最近邻纹理查找的相同方法解决了这个问题。浮点步长变量(大于零)下一个较低的索引,但是当 'floor(i*step)' 大于 'i' 时,它需要第一次跳转。

   function simplify(array, vertices){

      vertices = vertices || 1;///No div by zeros please :)

      var result = [];

      var step = array.length/vertices;

      for(var i=0;i<vertices;i++){
         result.push(array[Math.floor(step*i)]);
      }

      return result;

   }


//Testing it out
   var testarr = [];

   for(var ai=0;ai<51;ai++){
      testarr[ai] = {
         x:ai,
         y:10*ai
      }
   }

   console.log(testarr.slice(0));

   var ret = simplify(testarr, 29);

   console.log(ret.slice(0));

顺便说一句,

   function simplify_bilinear(array, vertices){

      var result = [];

      var step = array.length/vertices;

      for(var i=0;i<vertices;i++){
         var fistep = Math.floor(i*step);//The nearest neighbor index
         var current = array[fistep];//This element
         var next = array[fistep+1];//The next element
         var mix = (i*step)-fistep;//The fractional ratio between them. As this approaches 1, the mix approaches the next value.
         //mix = mix * mix * (3 - 2 * mix);//Optional (s-curve) easing between the positions. Better than linear, anyway.
         //Alternately to the above//mix = Math.sin((mix*2 - 1)*Math.PI)*.5+.5;///for a sinusoid curve
         //True Bezier would be optimal here but beyond this scope 
         var mixed_point = {
            x:current.x+(next.x-current.x)*mix,//basic mixing, ala 'mix' in your average math library
            y:current.y+(next.y-current.y)*mix,
         }
         result.push(mixed_point);
      }

      return result;

   }

是一个双线性 mag-filter,如果你想增加计数而不是降低计数。如果所需长度 ('vertices') 大于 'array.length',这可能会分支。也是软件音频合成的有用算法。