Math 值重映射

Math 值重映射,math,processing,Math,Processing,处理功能非常强大,我一直在使用: map(值、低1、高1、低2、高2) 它将值(其预期范围为low1到high1)重新映射到目标范围low2到high2) 我想理解它背后的数学原理,这样我就可以在其他语言中使用它。 有人想扔我一根骨头帮我逆向工程吗?我知道这是一个被重新缩放和重新偏移的lerp。。。今天早上感觉脑死亡。根据你的描述,它应该这样做,对吗 low2 + (value - low1) * (high2 - low2) / (high1 - low1) 找出你在第一个范围内的距离,

处理功能非常强大,我一直在使用:

map(值、低1、高1、低2、高2)

它将
(其预期范围为
low1
high1
)重新映射到目标范围
low2
high2

我想理解它背后的数学原理,这样我就可以在其他语言中使用它。
有人想扔我一根骨头帮我逆向工程吗?我知道这是一个被重新缩放和重新偏移的lerp。。。今天早上感觉脑死亡。

根据你的描述,它应该这样做,对吗

low2 + (value - low1) * (high2 - low2) / (high1 - low1)

找出你在第一个范围内的距离,用范围大小的比率缩放该距离,这就是你应该在第二个范围内的距离。

我想补充一点,这有时有助于找到low1和high1之间的系数,以便你可以在将系数用作LERP的t之前用曲线对其进行调整

因此,t=(value-low1)/(high1-low1)以获得行low1到high1中值的相对位置

然后,您可以使用一些曲线滤波器(例如,gamma、bias、gain等)来调节t,如果要限制超过设定下限和上限的值,还可以将t钳制在0和1之间


然后将t用于low2和high2之间的LERP,如:finalvalue=low2*(1-t)+high2*t处理是开源的。您可以查看
map()
函数

静态公共最终浮点映射(浮点值,
浮动开始1,浮动停止1,
浮动开始2,浮动停止2){
浮动输出=
start2+(stop2-start2)*((value-start1)/(stop1-start1));
字符串错误=null;
如果(传出!=传出){
badness=“NaN(不是数字)”;
}else if(传出==浮点.负_无穷大||
传出==浮点。正(无穷大){
badness=“无限”;
}
if(坏!=null){
最终字符串消息=
format(“调用的映射(%s,%s,%s,%s,%s),返回%s”,
nf(值)、nf(开始)、nf(停止1),
nf(start2),nf(stop2),不良;
PGraphics.showWarning(msg);
}
返出;
}
具体来说,您正在寻找以下代码行:

浮点输出=
start2+(stop2-start2)*((value-start1)/(stop1-start1));

如果有人想知道是否有一个无浮动的版本可以尽可能保持精度,我做了如下:

int remap(int value, int input_min, int input_max, int output_min, int output_max)
{
    const long long factor = 1000000000;

    long long output_spread = output_max - output_min;
    long long input_spread = input_max - input_min;

    long long l_value = value;

    long long zero_value = value - input_min;
    zero_value *= factor;
    long long percentage = zero_value / input_spread;

    long long zero_output = percentage * output_spread / factor;

    long long result = output_min + zero_output;

    return (int)result;
}
似乎对我有效,未经过广泛测试(例如,最大值小于最小值未经测试)

其背后的想法是,通过使用更大的类型来扩大原始值,从而使除法产生更大的数字,从而获得更高的精度