Jak przekonwertować liczbę z jednego zestawu min \ max na inny zestaw min \ max? [Zamknięte]

19

Generuję tereny i mam bibliotekę perlin, która podaje mi losowe liczby od -1 do +1. Chcę przekonwertować to na skalę 0-255. Jak to zrobić w odpowiedni sposób?

Tracja
źródło

Odpowiedzi:

23

Podstawowa formuła to:

Result := ((Input - InputLow) / (InputHigh - InputLow))
          * (OutputHigh - OutputLow) + OutputLow;

Twój przypadek:

Wynik: = (( Input - -1 ) / ( 1 - -1 ) * ( 255 - 0 ) + 0 ;

Stąd możesz zoptymalizować konwersję, jeśli twoje współczynniki są statyczne, ale kompilator prawdopodobnie zrobi to samo.

Wynik: = (( Input - -1 ) / 2 ) * 255 + 0 ;

Wynik: = Dane wejściowe * 127,5 + 127,5 ;

Kromster mówi, że popiera Monikę
źródło
2
Ta odpowiedź była najbardziej sensowna dla mojego mózgu programisty. :) „Dziękuję” wszystkim innym za ich wspaniałe odpowiedzi.
Thraka
10

Zakres -1do 1jest całkowitym zakresem 2. Musisz więc odpowiednio skalować, aby dostać się do 255. Coś takiego:

(randomPerlin + 1.0) * 127.5

Więc najpierw dodajesz 1, aby 0..2następnie pomnożyć przez, 127.5aby uzyskać zakres0..255

grzmot
źródło
3

Dzięki sile skalowania i stronniczości.

Od wartości odejmij minimalną wartość zakresu. To da ci wartość z zakresu [0..2].

Podziel to przez szerokość zakresu źródłowego, dając wartość z zakresu [0..1].

Pomnóż to przez szerokość zakresu docelowego, dając wartość z zakresu [0..255].

Dodaj podstawę zakresu docelowego, aby uzyskać wartość w zakresie docelowym, który w tym przypadku jest taki sam jak w poprzednim kroku.

W podsumowaniu:

            (v - (-1.0)) 
v' = 0 + ---------------- * (255 - 0)
          (1.0 - (-1.0))
Lars Viklund
źródło
3
oldRange = oldMax - oldMin
newRange = newMax - newMin

newValue = ((oldValue - oldMin) * newRange / oldRange) + newMin

Mam nadzieję że to pomoże.

funkcjonionoid
źródło
2

Przetłumacz zakres wejściowy, aby uzyskać min do zera przez dodanie 1 (ujemna wartość minimalnego wejścia) -1 .. 1 -> 0 .. 2

Ponieważ zakres wyjściowy zaczyna się od zera, nie rób nic dla tego.

Skaluj nowy zakres wejściowy, aby pasował do zakresu wyjściowego, jest to łatwe, ponieważ teraz oba zaczynają się od zera: pomnóż wartość przez 255/2 0..2 * 2/255 -> 0..255

Gotowy!

Przykład:

0,5 pójdzie: (0,5 + 1) * 127,5 = 191,25 -0,5 pójdzie: (-0,5 + 1) * 127,5 = 63,75

Valmond
źródło
2

Powiedzmy, że xto oryginalne wejście i yoczekiwane wyjście. Mamy co najmniej dwa punkty (x, y) (-1, 0) (1, 255)

Ponieważ chcemy wykonać interpolację liniową , możemy przyjrzeć się równaniu formy y = m*x + c

Z powyższymi dwoma punktami możemy rozwiązać mi c Gdy to zrobisz, otrzymasz równanie transformacji.

Uwaga: ta metoda działa również w przypadku innych typów równań. np. jeśli chcesz interpolacji wykładniczej lub kwadratowej.

Ankush
źródło
W naszej dziedzinie, wspólny sens interpolacji liniowej bywa, że mieszają się liniowo pomiędzy dwiema wielkościami z mieszania czynnika tak: v = (1-a)*x + (a)*y. Nie rozumiem, w jaki sposób ta odpowiedź ma duże znaczenie dla zadanego pytania, ponieważ wszystko, czego chce, to mapowanie zasięgu.
Lars Viklund
chodzi o to, że dwa punkty na płaszczyźnie jednoznacznie definiują linię. możemy traktować mapowanie zasięgu jako linię prostą. i znamy dwa punkty na tej linii. jego rozwiązanie da równanie liniowe. Być może interpolacja liniowa nie jest tutaj właściwym słowem, ale chciałem mieć na myśli zbiór wewnętrznych punktów między tymi dwoma punktami na tej linii.
Ankush,