价值重新映射

时间:2010-08-10 17:12:08

标签: math processing

处理具有我一直使用的强大功能:

map(value, low1, high1, low2, high2)

http://processing.org/reference/map_.html

它将value(预期范围为low1high1)重新映射到low2high2的目标范围。

我想了解它背后的数学因此我可以在其他语言中使用它。 有人想给我一块骨头并帮我逆向工程吗?我知道这是一个重新缩放并重新抵消的lerp ...今天早上感觉脑死了。

4 个答案:

答案 0 :(得分:29)

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

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

查看您进入第一个范围的距离,按范围大小的比例缩放该距离,以及您应该在第二个范围内的距离。

答案 1 :(得分:3)

处理是开源的。您可以查看map()函数here

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));

答案 2 :(得分:1)

我想补充一点,有时候找到low1和high1之间的因子很有用,这样你就可以在使用因子作为LERP的t之前用曲线对其进行调制。

所以,t =(value-low1)/(high1-low1)得到行中low1到high1的相对位置。

然后你可以用一些曲线滤波器调制t,例如,伽马,偏置,增益等。如果要限制超过设定低点和高点的值,也可以将t钳位在0和1之间。

然后使用t作为low2和high2之间的LERP,如:finalvalue = low2 *(1-t)+ high2 * t

答案 3 :(得分:1)

任何人都想知道是否有一种尽可能保持精度的无浮点版本,我做到了:

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;
}

似乎对我有用,未经广泛测试(例如,未经测试,max小于min)。

其背后的想法是通过使用更大的类型来扩大原始值,以便除法产生更大的数字-这将导致更高的精度。