受控数字尺度映射
Controled number scale mapping
我需要将以度为单位的旋转角度刻度映射到从 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);
但是,淡入和淡出太慢,当光强度达到最大值时,只留下一小段时间。我需要更多地控制比例映射的完成方式 - 我该如何实现?
如前所述,您可以通过 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>
如果您需要一个从一个数字上升到一个更高数字的比例(这就是我所要求的),上面@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);
}
张贴在这里以防对其他人有用。
我需要将以度为单位的旋转角度刻度映射到从 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);
但是,淡入和淡出太慢,当光强度达到最大值时,只留下一小段时间。我需要更多地控制比例映射的完成方式 - 我该如何实现?
如前所述,您可以通过 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>
如果您需要一个从一个数字上升到一个更高数字的比例(这就是我所要求的),上面@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);
}
张贴在这里以防对其他人有用。