使用ease参数返回exp值数组

时间:2017-06-07 00:37:03

标签: javascript algorithm math

我需要一个方法来获得一个整数区间,该区间在两个整数(min,max)的范围内,并带有一个缓动值(-100; 100)来定义从左到右的这个值的“加速度” 。

如何使用

foo(min, max, samples, ease);
  • min 是start int(included)
  • max 是结束int(包含)
  • 示例要返回的值的数量
  • 轻松轻松从-100到100

作为回报,我需要一个整数数组。

预期

foo(5, 20, 4, 0); // [5, 10, 15, 20]
foo(5, 20, 4, 1.3); // [5, 7, 12, 20]
foo(5, 20, 4, 100); // [5, 16, 18, 20]
foo(5, 20, 4, -100); // [5, 7, 9, 20]

从上到下(最后三个结果带有奇特的返回值):

  • 从5到20的4个值,线性进展。
  • 4个值,从5到20,进展很小。
  • 快速进展的4个值。
  • 4个值,进展非常缓慢。

我尝试了什么

我尝试使用sin曲线创建一个javascript方法,但返回值不包含start和last值,而我的easy值可能(肯定是强制性的)不正确:

function foo(min, max, samples, ease) {
  const ret = [];
  for (var i = min/max; i < 1; i += 1/samples) {
    ret.push(Math.round((1 - Math.sin((1 - i) * Math.PI / ease)) * max)); 
  }
  return ret;
}

创建这样的方法的最佳方法是什么?

1 个答案:

答案 0 :(得分:2)

使用指数曲线代替正弦波。使用3的幂,您甚至可以得到您描述的结果(在端点[-100, 100]

&#13;
&#13;
//simple linear interpolation
var interpolate = (a,b,t) => a*(1-t) + b*t;

function foo(min, max, samples, ease=0){
	var pow = interpolate(1, ease<0? 3: 1/3, Math.abs(+ease || 0)/100);
	var arr = Array(+samples);
	for(var i=0; i<arr.length; ++i)
		arr[i] = interpolate(min, max, Math.pow(i / (samples-1), pow));
	return arr;
}

function round(v){ return Math.round(v * 1E5)/1E5 }
foo(-100, 100, 11).forEach(ease => console.log("ease: %s values: [ %s ]", ease, foo(5, 20, 4, ease).map(round).join(", ")))
&#13;
.as-console-wrapper{top:0;max-height:100%!important}
&#13;
&#13;
&#13;