Estou tentando converter um intervalo de números para outro, mantendo a proporção. Matemática não é meu ponto forte.
Eu tenho um arquivo de imagem em que os valores dos pontos podem variar de -16000,00 a 16000,00, embora o intervalo típico possa ser muito menor. O que eu quero fazer é compactar esses valores no intervalo inteiro de 0 a 100, onde 0 é o valor do menor ponto e 100 é o valor do maior. Todos os pontos intermediários devem manter uma proporção relativa, embora alguma precisão esteja sendo perdida. Eu gostaria de fazer isso em python, mas mesmo um algoritmo geral deve ser suficiente. Eu preferiria um algoritmo em que o intervalo mínimo / máximo ou qualquer um dos intervalos possa ser ajustado (ou seja, o segundo intervalo poderia ser de -50 a 800 em vez de 0 a 100).
Respostas:
Ou um pouco mais legível:
Ou se você deseja proteger para o caso em que o intervalo antigo é 0 ( OldMin = OldMax ):
Observe que, nesse caso, somos forçados a escolher um dos possíveis novos valores de intervalo arbitrariamente. Dependendo do contexto, as escolhas sensatas podem ser:
NewMin
( ver exemplo )NewMax
ou(NewMin + NewMax) / 2
fonte
Essa é uma conversão linear simples.
Assim, converter 10000 na escala de -16000 a 16000 em uma nova escala de 0 a 100 produz:
fonte
Na verdade, existem alguns casos em que as respostas acima quebrariam. Tais como valor de entrada incorreto, faixa de entrada incorreta, faixas de entrada / saída negativas.
fonte
Existe uma condição, quando todos os valores que você está verificando são os mesmos, em que o código do @ jerryjvl retornaria NaN.
fonte
Eu não desenterrei o BNF para isso, mas a documentação do Arduino tinha um ótimo exemplo da função e sua falha. Eu era capaz de usar isso no Python simplesmente adicionando uma renomeação de definição para remapear (o mapa de causas é incorporado) e removendo os tipos de conversão e chaves (ou seja, basta remover todos os 'long's').
Original
Pitão
https://www.arduino.cc/en/reference/map
fonte
Na listagem fornecida pelo PenguinTD, não entendo por que os intervalos são invertidos, ele funciona sem ter que reverter os intervalos. A conversão do intervalo linear é baseada na equação linear
Y=Xm+n
, ondem
en
são derivados dos intervalos fornecidos. Em vez de se referir aos intervalos comomin
emax
, seria melhor referir-se a eles como 1 e 2. Portanto, a fórmula seria:Onde
Y=y1
quandoX=x1
eY=y2
quandoX=x2
.x1
,x2
,y1
Ey2
pode ser dada qualquerpositive
ounegative
valor. Definir a expressão em uma macro a torna mais útil, podendo ser usada com qualquer nome de argumento.A
float
conversão garantiria a divisão de ponto flutuante no caso em que todos os argumentos sejaminteger
valores. Dependendo da aplicação, pode não ser necessário verificar os intervalosx1=x2
ey1==y2
.fonte
float RangeConv(float input, float x1, float x2, float y1, float y2) { return (((input - x1) * (y2 - y1)) / (x2 - x1)) + y1; }
Aqui estão algumas funções curtas do Python para facilitar a cópia e colar, incluindo uma função para dimensionar uma lista inteira.
Que pode ser usado assim:
No meu caso, eu queria escalar uma curva logarítmica, assim:
fonte
Eu usei essa solução em um problema que estava resolvendo em js, então pensei em compartilhar a tradução. Obrigado pela explicação e solução.
fonte
Variante C ++
Eu achei a solução do PenguinTD útil, então eu a portava para C ++, se alguém precisar:
fonte
Porta PHP
Achei a solução do PenguinTD útil, então eu a transportei para o PHP. Fique a vontade!
fonte
Aqui está uma versão Javascript que retorna uma função que redimensiona para intervalos de origem e destino predeterminados, minimizando a quantidade de computação que deve ser feita a cada vez.
Aqui está um exemplo de uso dessa função para dimensionar 0-1 em -0x80000000, 0x7FFFFFFF
fonte
Proposta de atalho / simplificada
Wayne
fonte
NewRange/OldRange
aqui?Pessoalmente, uso a classe helper que suporta genéricos (compatível com Swift 3)
fonte
Este exemplo converte a posição atual da música em um intervalo de ângulo de 20 a 40.
fonte
Solução de liner de compreensão de lista
Versão mais longa
fonte
Versão Java
Sempre funciona, não importa como você o alimenta!
Deixei tudo expandido para facilitar o aprendizado. O arredondamento no final, é claro, é opcional.
fonte