Pregunta

Actualmente tengo un control al que necesito agregar la facilidad para aplicar varios niveles de agudeza (o sensibilidad). El problema se ilustra mejor como una imagen:

Gráfico http://img87.imageshack.us/img87/7886/control. png

Como puede ver, tengo ejes X e Y que tienen límites arbitrarios de 100, lo que debería ser suficiente para esta explicación. En la actualidad, mi control es la línea roja (comportamiento lineal), pero me gustaría agregar la capacidad para las otras 3 curvas (o más), es decir, si un control es más sensible, una configuración ignorará la configuración lineal e irá por una de las tres lineas. El punto de partida siempre será 0 y el punto de finalización siempre será 100.

Sé que un exponencial es demasiado empinado, pero parece que no puedo encontrar un camino a seguir. ¿Alguna sugerencia por favor?

¿Fue útil?

Solución

Las curvas que ha ilustrado se parecen mucho a las corrección de gamma curvas. La idea allí es que el mínimo y el máximo del rango permanecen igual que la entrada, pero el centro está doblado como lo tiene en sus gráficos (lo que podría notar es no el arco circular que haría obtener de la implementación del coseno).

Gráficamente, se ve así:

 texto alternativo
(fuente: wikimedia.org )

Entonces, con eso como inspiración, aquí están las matemáticas ...

Si sus valores de x iban de 0 a 1, la función es bastante simple:

y = f(x, gamma) = x ^ gamma

Agregue un valor xmax para escalar (es decir, x = 0 a 100), y la función se convierte en:

y = f(x, gamma) = ((x / xmax) ^ gamma) * xmax

o alternativamente:

y = f(x, gamma) = (x ^ gamma) / (xmax ^ (gamma - 1))

Puede llevar esto un paso más allá si desea agregar un xmin distinto de cero.

Cuando gamma es 1, la línea siempre es perfectamente lineal (y = x). Si x es menor que 1, su curva se dobla hacia arriba. Si x es mayor que 1, su curva se dobla hacia abajo. El valor recíproco de gamma convertirá el valor nuevamente al original (x = f (y, 1 / g) = f (f (x, g), 1 / g).

Simplemente ajuste el valor de gamma según sus propios gustos y necesidades de aplicación. Dado que desea dar al usuario múltiples opciones para '' mejora de la sensibilidad '', es posible que desee ofrecer a sus usuarios opciones en una escala lineal, por ejemplo, que va de -4 (menos sensible) a 0 (sin cambios) a 4 (la mayoría sensible) y escale sus valores de gamma internos con una función de potencia. En otras palabras, brinde al usuario opciones de (-4, -3, -2, -1, 0, 1, 2, 3, 4), pero traduzca eso a valores gamma de (5.06, 3.38, 2.25, 1.50, 1.00 , 0,67, 0,44, 0,30, 0,20).

Codificando que en C # podría verse más o menos así:

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);
    }
}

Para usarlo, cree un nuevo Ajustador de sensibilidad, establezca el nivel de sensibilidad de acuerdo con las preferencias del usuario (ya sea utilizando el constructor o el método, y -4 a 4 probablemente serían valores de nivel razonables) y llame a Ajustar (x) para obtener el valor de salida ajustado. Si quisiera un rango más amplio o más estrecho de niveles razonables, reduciría o aumentaría ese valor 1.5 en el método SetSensitivityLevels. Y, por supuesto, el 100 representa su valor x máximo.

Otros consejos

Propongo una fórmula simple, que (creo) captura su requerimiento. Para tener un '' cuarto de círculo '' completo, que es su caso extremo, usaría (1-cos ((x * pi) / (2 * 100))) * 100 .

Lo que sugiero es que tome un promedio ponderado entre y = x e y = (1-cos ((x * pi) / (2 * 100))) * 100. Por ejemplo, para tener muy cerca de lineal (99% lineal), tome:

y = 0.99*x + 0.01*[(1-cos((x*pi)/(2*100)))*100]

O más generalmente, digamos que el nivel de linealidad es L, y está en el intervalo [0, 1], su fórmula será:

y = L*x + (1-L)*[(1-cos((x*pi)/(2*100)))*100]

EDITAR: cambié cos (x / 100) a cos ((x * pi) / (2 * 100)) , porque el resultado cos sería en el rango [1,0] X debe estar en el rango de [0, pi / 2] y no [0,1], perdón por el error inicial.

Probablemente esté buscando algo como interpolación polinomial . Una interpolación cuadrática / cúbica / cuártica debería proporcionarle el tipo de curvas que muestra en la pregunta. Las diferencias entre las tres curvas que muestra probablemente podrían lograrse simplemente ajustando los coeficientes (que determinan indirectamente la inclinación).

El gráfico de y = x ^ p para x de 0 a 1 hará lo que desee, ya que varía p de 1 ( que dará la línea roja) hacia arriba. A medida que p aumenta, la curva se 'empujará' más y más. p no tiene que ser un número entero.

(Tendrá que escalar para obtener de 0 a 100, pero estoy seguro de que puede resolverlo)

Voto por la idea general de Rax Olgud, con una modificación:

y = alpha * x + (1-alpha)*(f(x/100)*100)

alt textmal http://phac.htm / Calcular / MSP / MSP4501967d41e1aga1b3i00004bdeci2b6be2a59b? MSPStoreType = image / gif & amp; s = 6

donde f (0) = 0, f (1) = 1, f (x) es superlineal, pero no sé dónde está este '' cuarto de círculo '' idea de por qué 1-cos (x) sería una buena opción.

Sugeriría f (x) = x k donde k = 2, 3, 4, 5, lo que sea que le dé el grado de inclinación deseado para & amp; alpha = 0. Elija un valor para k como un número fijo, luego varíe a para elegir su curva particular.

Para problemas como este, a menudo obtendré algunos puntos de una curva y los lanzaré a través de un programa de ajuste de curvas. Hay un montón de ellos por ahí. Aquí hay uno con una prueba gratuita de 7 días.

He aprendido mucho probando diferentes modelos. A menudo puede obtener una expresión bastante simple para acercarse a su curva.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top