受控数字比例映射

时间:2018-07-14 13:15:04

标签: javascript three.js physics

我需要将以度为单位的旋转角度比例映射到从0.0到0.9的光强度比例(旋转的太阳)。这是我正在使用的映射功能:

function map (num, in_min, in_max, out_min, out_max)
{
    return (num - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

//(degree, degree in min, degree in max, light intensity out min, light intensity out max
var fade = map(30, 180, 360, 0.0, 0.9);

但是,当光强度达到最大时,淡入和淡出速度太慢。我需要对比例映射的完成方式进行更多控制-如何实现?

2 个答案:

答案 0 :(得分:1)

如果您需要一个从数字到更高数字的标度,那么@Manuel Otto的答案是正确的(这就是我要的)。但是,我需要更大的灵活性,因为在测试时正在调整我的太阳位置即席调节,并且下面的最终功能也可以从一个数字运行到一个较小的数字(因为它的度数会在360重置为0)-因此例如180-> 60(180至360,然后0至60 = 240度):

//input degree, minimum degree possible, maximum degree possible, scale minimum, scale maximum, speed of scale fades (0.0 - 1.0 = fast to slow) 
function map(num, in_min, in_max, out_min, out_max, factor)
{
    //if input degree is greater than minimum degree possible
    if (num >= in_min)
    {
        //simple subtraction
        var delta = Math.max(0, num - in_min);
    } else {
        //subtract from 360 and add the input degree
        var delta = Math.max(0, ((360 - in_min) + num));
    }

    //if the maximum degree possible is greater than the minimum degree possible
    if (in_max >= in_min)
    {
        //simple subtraction
        var scale = delta / (in_max - in_min);
    } else {
        //subtract from 360 and add the maximum degree possible
        var scale = delta / ((360 - in_min) + in_max);
    }

    return Math.pow(Math.min(1, scale * 2) - Math.max(0, scale * 2 - 1), factor);
}

将其张贴在这里,以防其他人使用。

答案 1 :(得分:0)

正如已经说过的那样,您可以使用Math.pow(x,<1)实现初始的快速变化和长期的低变化。

要使其渐隐然后再次渐隐,可以将值缩放2,然后用该值减去大于1的值。

function map(num, in_min, in_max, out_min, out_max, factor)
{
  var delta = Math.max(0,num-in_min)
  var scale = delta/(in_max-in_min)

  return Math.pow(Math.min(1,scale*2)-Math.max(0,scale*2-1),factor)
}

factor为1时,它是线性的。小于1时就是多项式。

请参见插图:

function map(num, in_min, in_max, out_min, out_max, factor)
{
  var delta = Math.max(0,num-in_min)
  var scale = delta/(in_max-in_min)
  
  return Math.pow(Math.min(1,scale*2)-Math.max(0,scale*2-1),factor)
}



// UI

var degrees_slider = document.getElementById('degrees')
var factor_slider = document.getElementById('factor')
var degrees_disp = document.getElementById('degrees_disp')
var factor_disp = document.getElementById('factor_disp')
var intensity_disp = document.getElementById('intensity_disp')

degrees_slider.oninput = factor_slider.oninput = update

function update(){
  var num = degrees_slider.value
  var fact = factor_slider.value
  
  degrees_disp.innerHTML = num
  factor_disp.innerHTML = fact
  intensity_disp.innerHTML = toPercent(map(num, 180, 360, 0.0, 0.9, fact))
  
}

function toPercent(val){
  return Math.round(val*100)+'%'
}

update()
#intensity_disp{
  font-size: 32pt;
  margin-top: 25px;
}
<label for="degrees">Degrees</label>
<br>
<input type="range" id="degrees" min="0" max="360" step="1"/>
<span id="degrees_disp"></span>

<br><br>

<label for="degrees">Linearity</label>
<br>
<input type="range" id="factor" min="0" max="1" step="0.01"/>
<span id="factor_disp"></span>

<div id="intensity_disp"></div>