31 Stimmen

Wert-Remapping

Processing hat eine großartige Funktion, die ich ständig benutze:

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

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

Sie bildet neu ab value (mit einem erwarteten Bereich von low1 a high1 ) in einen Zielbereich von low2 a high2 ).

Ich möchte die Mathematik dahinter verstehen, damit ich sie in anderen Sprachen verwenden kann. Kann mir jemand einen Gefallen tun und mir beim Reverse Engineering helfen? Ich verstehe, dass es ein lerp ist, das neu skaliert und neu verschoben wurde... ich fühle mich heute Morgen hirntot.

58voto

Cascabel Punkte 449595

Nach Ihrer Beschreibung müsste das doch der Fall sein, oder?

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

Stellen Sie fest, wie weit Sie im ersten Bereich sind, skalieren Sie diesen Abstand mit dem Verhältnis der Größen der Bereiche, und das ist der Abstand, den Sie im zweiten Bereich haben sollten.

8voto

Kevin Workman Punkte 40446

Die Verarbeitung ist Open-Source. Sie können sich die map() Funktion aquí .

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

Genauer gesagt, suchen Sie nach dieser Codezeile:

float outgoing =
      start2 + (stop2 - start2) * ((value - start1) / (stop1 - start1));

2voto

probiner Punkte 91

Ich möchte hinzufügen, dass es manchmal nützlich ist, den Faktor zwischen low1 und high1 zu finden, damit man ihn mit einer Kurve modulieren kann, bevor man den Faktor als LERP's t verwendet.

Also, t = (Wert-niedrig1)/(hoch1-niedrig1), um die relative Position des Wertes in der Zeile niedrig1 zu hoch1 zu erhalten.

Dann können Sie t mit einem Kurvenfilter modulieren, z. B. Gamma, Bias, Gain usw. Sie können t auch zwischen 0 und 1 klemmen, um Werte zu begrenzen, die über die eingestellten Tiefst- und Höchstwerte hinausgehen.

Und dann verwenden Sie das t für den LERP zwischen low2 und high2 wie folgt: finalvalue = low2*(1-t) + high2*t

1voto

Gizmo Punkte 1798

Für alle, die sich fragen, ob es eine Version ohne Schwimmer gibt, die so viel Präzision wie möglich beibehält, habe ich diese erstellt:

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

Scheint bei mir zu funktionieren, wurde aber nicht ausgiebig getestet (z.B. max ist kleiner als min wurde nicht getestet).

Die Idee dahinter ist, den ursprünglichen Wert durch Verwendung eines größeren Typs zu vergrößern, so dass Divisionen größere Zahlen ergeben - was zu einer höheren Genauigkeit führt.

0voto

In meinem Fall habe ich einen Ausdruck (var * amount)-shift verwendet wobei var der Wert ist amount ist die Anzahl der Blendshapes und shift der Wert ist, der auf dem Index des Blendshapes basiert (shift um 1 und man erhält 0, wenn der Wert 1 ist, so dass das nächste Blendshape beginnt)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X