Bereich von Zahlen auf anderen Bereich umrechnen

Hallo, ich hätte mal eine Frage bezüglich etwas mathematischem, bei dem ich jedes mal wieder Probleme habe. Angenommen ich habe einen float, der Zahlen von A bis B sein kann, den ich jetzt aber auf den Bereich von C bis D umrechnen muss. Meistens sind es schöne Zahlen, wie [0,1] auf [-100,100] oder ähnliches, aber wie mache ich es bei z.b. [3,7] auf [-17,50]? Gibt es ein System um die Formel aufzustellen?

Da hilft reine Logik :wink:

Ich würde die Intervalle beide normieren (also auf [0,1] bringen) und dann die Formeln zusammensetzen. Beispiel:

[3,7] normieren:
Intervallbreite: [tex]i_1 = 3-7 = 4[/tex]
Offset: [tex]o_1 = 3[/tex]
Formel um zu normieren: [tex]\frac{x_1 - o_1}{i_1} = \frac{x_1 - 3}{4} = x_{\mathrm{norm}}[/tex]

Das selbe für das zweite Intervall:
[-17,50]
Intervallbreite: [tex]i_2 = 67[/tex]
Offset: [tex]o_2 = -17[/tex]
Formel: [tex]\frac{x_2 + 17}{67} = x_{\mathrm{norm}}[/tex]

Gleichsetzen:
[tex]\frac{x_1 - 3}{4} = \frac{x_2 + 17}{67}[/tex]
Jetzt noch ein bisschen Formeln schubsen und du hast deine Rechenregel von [tex]x_1[/tex] nach [tex]x_2[/tex] und umgekehrt.

Allgemein:
[tex]\frac{x_1 - o_1}{i_1} = \frac{x_2 - o_2}{i_2}[/tex]
Bzw:
[tex]x_1 = \frac{(x_2 - o_2)i_1}{i_2}+o_1[/tex]

geht doch direkt

wenn man vom Intervall [a,b] auf das Intervall [c,d] will, dann ist die gesuchte Funktion genau die gerade durch zwei Punkte (a,c) und (b,d)

also wie in der Schule gelernt: **f(x)=((d-c)/(b-a))x+d-((d-c)/(b-a))b die Gerade mit der Steigung m=(d-c)/(b-a)

hinschauen zeigt f(a)=ma+d-mb=m(a-b)+d=(c-d)+d=c und f(b)=mb+d-mb=d

WOW, so einfach kanns gehen. Vielen Dank

[QUOTE=Bleiglanz]geht doch direkt
[…][/QUOTE]

Schöner Ansatz! Die Idee, das Intervall von der X- auf die Y-Achse zu projizieren finde ich sehr elegant.
Die Formel lässt sich noch ein kleines bisschen zusammenfassen:
[tex]f(x)=\frac{dx-cx+bc-da}{b-a}[/tex]

Für diejenigen, denen es noch nicht aufgefallen ist: die Formel ist dieselbe wie die, die ich oben gepostet habe, nur dass die Intervalle und Offsets eingesetzt sind und danach etwas zusammengefasst.

Oft (nicht immer, aber sehr oft) ist es in solchen Fällen praktisch, die Zahlenbereiche, um die es geht, zu normalisieren - also auf das Intervall [0,1] umzurechnen. Dann ließe es sich zurückführen auf eine “Normalisierung” (die eine gegebene Zahl aus einem bestimmten Intervall auf eine Zahl aus [0,1] umrechnet), und einer “Skalierung” (die eine gegebene Zahl aus dem Intervall [0,1] auf die gewünschte Zahl aus dem Zielintervall umrechnet).

Ob das auch hier angebracht ist, kann man nicht wissen…

import java.util.Locale;

public class Normalization
{
    public static double normalize(double input, double min, double max)
    {
        return (input-min)/(max-min);
    }
    public static double scale(double input, double min, double max)
    {
        return min + input * (max-min);
    }
    public static void main(String[] args)
    {
        double minIn = 3;
        double maxIn = 7;
        double minOut = -17;
        double maxOut = 50;
        
        for (double input=minIn; input<=maxIn; input+=0.1)
        {
            double alpha = normalize(input, minIn, maxIn);
            double output = scale(alpha, minOut, maxOut);
            System.out.println(
                "Input: "+String.format(Locale.ENGLISH, "%5.2f", input)+
                " normalized: "+String.format(Locale.ENGLISH, "%5.2f", alpha)+
                " output: "+String.format(Locale.ENGLISH, "%5.2f", output));
        }
    }    
}