Sembra un semplice problema grafico
Domanda
Al momento ho un controllo al quale devo aggiungere la struttura per applicare varie acutezza (o sensibilità). Il problema è meglio illustrato come immagine:
Grafico http://img87.imageshack.us/img87/7886/control. png
Come puoi vedere, ho un ascesso X e Y che hanno entrambi limiti arbitrari di 100, che dovrebbe bastare per questa spiegazione. Al momento, il mio controllo è la linea rossa (comportamento lineare), ma vorrei aggiungere l'abilità per le altre 3 curve (o più), ovvero se un controllo è più sensibile, un'impostazione ignorerà l'impostazione lineare e sceglierne una delle tre linee. Il punto iniziale sarà sempre 0 e il punto finale sarà sempre 100.
So che un esponenziale è troppo ripido, ma non riesco a immaginare una via da seguire. Qualche suggerimento per favore?
Soluzione
Le curve che hai illustrato assomigliano molto a correzione gamma . L'idea è che il minimo e il massimo dell'intervallo rimangono gli stessi dell'input, ma il centro è piegato come hai nei tuoi grafici (che potrei notare è non l'arco circolare che vorresti ottenere dall'implementazione del coseno).
Graficamente, sembra così:
(fonte: wikimedia.org )
Quindi, con quello come ispirazione, ecco la matematica ...
Se i valori x variano da 0 a 1, la funzione è piuttosto semplice:
y = f(x, gamma) = x ^ gamma
Aggiungi un valore xmax per il ridimensionamento (ovvero x = da 0 a 100) e la funzione diventa:
y = f(x, gamma) = ((x / xmax) ^ gamma) * xmax
o in alternativa:
y = f(x, gamma) = (x ^ gamma) / (xmax ^ (gamma - 1))
Puoi fare un ulteriore passo avanti se desideri aggiungere un xmin diverso da zero.
Quando gamma è 1, la linea è sempre perfettamente lineare (y = x). Se x è inferiore a 1, la curva si piega verso l'alto. Se x è maggiore di 1, la curva si piega verso il basso. Il valore reciproco di gamma ripristinerà il valore originale (x = f (y, 1 / g) = f (f (x, g), 1 / g).
Regola semplicemente il valore della gamma in base ai tuoi gusti e alle tue esigenze applicative. Poiché desideri offrire all'utente più opzioni per "miglioramento della sensibilità", potresti voler offrire agli utenti una scelta su una scala lineare, diciamo che va da -4 (meno sensibile) a 0 (nessuna modifica) a 4 (la maggior parte sensibile) e ridimensionare i valori gamma interni con una funzione di potenza. In altre parole, dai all'utente le scelte di (-4, -3, -2, -1, 0, 1, 2, 3, 4), ma traducilo in valori gamma di (5,06, 3,38, 2,25, 1,50, 1,00 , 0,67, 0,44, 0,30, 0,20).
La codifica che in C # potrebbe assomigliare a questa:
public class SensitivityAdjuster {
public SensitivityAdjuster() { }
public SensitivityAdjuster(int level) {
SetSensitivityLevel(level);
}
private double _Gamma = 1.0;
public void SetSensitivityLevel(int level) {
_Gamma = Math.Pow(1.5, level);
}
public double Adjust(double x) {
return (Math.Pow((x / 100), _Gamma) * 100);
}
}
Per usarlo, crea un nuovo SensitivityAdjuster, imposta il livello di sensibilità in base alle preferenze dell'utente (usando il costruttore o il metodo e da -4 a 4 probabilmente sarebbero valori di livello ragionevoli) e chiama Adjust (x) per ottenere il valore di uscita regolato. Se si desidera un intervallo più ampio o più stretto di livelli ragionevoli, è necessario ridurre o aumentare tale valore 1.5 nel metodo SetSensitivityLevels. E ovviamente il 100 rappresenta il tuo valore x massimo.
Altri suggerimenti
Propongo una formula semplice, che (credo) cattura le tue esigenze. Per avere un "quarto di cerchio" completo, che è il tuo caso estremo, dovresti usare (1-cos ((x * pi) / (2 * 100))) * 100
.
Quello che suggerisco è di prendere una media ponderata tra y = xe y = (1-cos ((x * pi) / (2 * 100))) * 100. Ad esempio, per avere molto vicino a linear (99% linear), prendi:
y = 0.99*x + 0.01*[(1-cos((x*pi)/(2*100)))*100]
O più in generale, dire che il livello di linearità è L, ed è nell'intervallo [0, 1], la formula sarà:
y = L*x + (1-L)*[(1-cos((x*pi)/(2*100)))*100]
EDIT: ho modificato cos (x / 100)
in cos ((x * pi) / (2 * 100))
, perché per il risultato cos sarebbe nell'intervallo [1,0] X dovrebbe essere nell'intervallo di [0, pi / 2] e non [0,1], scusate l'errore iniziale.
Probabilmente stai cercando qualcosa come interpolazione polinomiale . Un'interpolazione quadratica / cubica / quartica dovrebbe darti il ??tipo di curve che mostri nella domanda. Le differenze tra le tre curve mostrate potrebbero probabilmente essere ottenute semplicemente regolando i coefficienti (che determinano indirettamente la pendenza).
Il grafico di y = x ^ p
per x
da 0 a 1 farà ciò che desideri man mano che vari p
da 1 ( che darà la linea rossa) verso l'alto. Man mano che p
aumenta, la curva verrà "spinta" sempre più. p
non deve essere un numero intero.
(Dovrai ridimensionare per ottenere da 0 a 100 ma sono sicuro che puoi risolverlo)
Voto per l'idea generale di Rax Olgud, con una modifica:
y = alpha * x + (1-alpha)*(f(x/100)*100)
dove f (0) = 0, f (1) = 1, f (x) è superlineare, ma non so dove sia questo "quarto di cerchio" l'idea è nata o perché 1-cos (x) sarebbe una buona scelta.
Suggerirei f (x) = x k dove k = 2, 3, 4, 5, qualunque cosa ti dia il grado desiderato di ripidezza per & amp; alpha = 0. Scegli un valore per k come numero fisso, quindi variare & # 945; per scegliere la tua curva particolare.
Per problemi come questo, spesso ottengo alcuni punti da una curva e lo lancio attraverso un programma di adattamento della curva. Ce ne sono un sacco là fuori. Eccone uno con una prova gratuita di 7 giorni.
Ho imparato molto provando diversi modelli. Spesso puoi ottenere un'espressione piuttosto semplice per avvicinarti alla tua curva.