Processing有一个我经常使用的很棒的功能:
map(value, low1, high1, low2, high2)
http://processing.org/reference/map_.html
该函数将期望范围为low1
到high1
的value
重新映射到目标范围low2
到high2
。
我想理解它背后的数学原理,以便在其他语言中使用它。有没有人能帮我倒推一下?我知道这是一个已重新缩放和重新偏移的lerp
...今天早上感觉有点脑残。
Processing有一个我经常使用的很棒的功能:
map(value, low1, high1, low2, high2)
http://processing.org/reference/map_.html
该函数将期望范围为low1
到high1
的value
重新映射到目标范围low2
到high2
。
我想理解它背后的数学原理,以便在其他语言中使用它。有没有人能帮我倒推一下?我知道这是一个已重新缩放和重新偏移的lerp
...今天早上感觉有点脑残。
根据您的描述,它应该做到这一点,对吗?
low2 + (value - low1) * (high2 - low2) / (high1 - low1)
找出你在第一个范围内的距离,按范围大小比例缩放该距离,这就是你应该在第二个范围内的位置。
Processing是开源的。你可以在这里查看map()
函数。
static public final float map(float value,
float start1, float stop1,
float start2, float stop2) {
float outgoing =
start2 + (stop2 - start2) * ((value - start1) / (stop1 - start1));
String badness = null;
if (outgoing != outgoing) {
badness = "NaN (not a number)";
} else if (outgoing == Float.NEGATIVE_INFINITY ||
outgoing == Float.POSITIVE_INFINITY) {
badness = "infinity";
}
if (badness != null) {
final String msg =
String.format("map(%s, %s, %s, %s, %s) called, which returns %s",
nf(value), nf(start1), nf(stop1),
nf(start2), nf(stop2), badness);
PGraphics.showWarning(msg);
}
return outgoing;
}
具体来说,您正在寻找这行代码:
float outgoing =
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;
}
对我来说似乎有效,没有进行全面测试(例如,最大值小于最小值未经过测试)。
背后的想法是通过使用更大的类型来扩大原始值,以便除法产生更大的数字 - 这将导致更高的精度。