it-swarm.com.de

Mathematische Zuordnung von Zahlen

Wie ordne ich Zahlen linear zwischen a und b zu, um zwischen c und d zu wechseln?.

Das heißt, ich will Zahlen zwischen 2 und 6 auf Zahlen zwischen 10 und 20 abbilden ... aber ich brauche den verallgemeinerten Fall.

Mein Gehirn ist gebraten.

81
Sam

Wenn Ihre Zahl X zwischen A und B liegt und Sie möchten, dass Y zwischen C und D liegt, können Sie die folgende lineare Transformation anwenden:

Y = (X-A)/(B-A) * (D-C) + C

Das sollte Ihnen das geben, was Sie wollen, obwohl Ihre Frage etwas mehrdeutig ist, da Sie das Intervall auch in umgekehrter Richtung abbilden könnten. Achten Sie einfach auf die Division durch Null und Sie sollten in Ordnung sein.

170
PeterAllenWebb

Teilen Sie, um das Verhältnis zwischen den Größen der beiden Bereiche zu erhalten, ziehen Sie dann den Startwert Ihres Anfangsbereichs ab, multiplizieren Sie ihn mit dem Verhältnis und addieren Sie den Startwert Ihres zweiten Bereichs. Mit anderen Worten,

R = (20 - 10) / (6 - 2)
y = (x - 2) * R + 10

Dadurch werden die Zahlen aus dem ersten Bereich im zweiten Bereich gleichmäßig verteilt.

18
Konrad Rudolph

Es wäre schön, diese Funktionalität in der Java.lang.Math-Klasse zu haben, da dies eine häufig benötigte Funktion ist und in anderen Sprachen verfügbar ist .. Hier eine einfache Implementierung:

final static double EPSILON = 1e-12;

public static double map(double valueCoord1,
        double startCoord1, double endCoord1,
        double startCoord2, double endCoord2) {

    if (Math.abs(endCoord1 - startCoord1) < EPSILON) {
        throw new ArithmeticException("/ 0");
    }

    double offset = startCoord2;
    double ratio = (endCoord2 - startCoord2) / (endCoord1 - startCoord1);
    return ratio * (valueCoord1 - startCoord1) + offset;
}

Ich setze diesen Kodex hier als Referenz für die Zukunft ein und kann jemandem helfen.

5
Sourabh Bhat

Abgesehen davon ist dies das gleiche Problem wie beim klassischen konvertieren von celcius nach farenheit, wenn Sie einen Nummernbereich abbilden möchten, der 0 - 100 (C) bis 32 - 212 (F) entspricht.

3
Metro

Jedes Einheitsintervall im ersten Bereich beansprucht (d-c)/(b-a) "Raum" im zweiten Bereich.

Pseudo:

var interval = (d-c)/(b-a)
for n = 0 to (b - a)
    print c + n*interval

Wie Sie mit der Rundung umgehen, liegt bei Ihnen.

1
Chris Cudmore
int srcMin = 2, srcMax = 6;
int tgtMin = 10, tgtMax = 20;

int nb = srcMax - srcMin;
int range = tgtMax - tgtMin;
float rate = (float) range / (float) nb;

println(srcMin + " > " + tgtMin);
float stepF = tgtMin;
for (int i = 1; i < nb; i++)
{
  stepF += rate;
  println((srcMin + i) + " > " + (int) (stepF + 0.5) + " (" + stepF + ")");
}
println(srcMax + " > " + tgtMax);

Bei Überprüfungen auf Division durch Null natürlich.

1
PhiLho

wenn Ihr Bereich von [a bis b] liegt und Sie ihn in [c bis d] zuordnen möchten, wobei x der Wert ist, den Sie zuordnen möchten Verwenden Sie diese Formel (lineare Abbildung).

double R = (d-c)/(b-a)
double y = c+(x*R)+R
return(y)
0
Mohamed Ashraf

Wenn Sie das Ergebnis umkehren möchten, verwenden Sie Folgendes:

reverseX = (B-A)*(Y-C)/(D-C) + A
0
Dejell