How to create a slider with a non-linear scale?
A good formula for the displayed value is a monotonous function such as a power curve, in the following form:
DisplayValue = A + B * Math.Exp(C * SliderValue);
The internal slider value (from 0 to 1 for instance) is obtained by inverting the formula:
SliderValue = Math.Log((DisplayValue - A) / B) / C;
Now how to obtain A, B and C? By using the three constraints you gave:
f(0.0) = 0
f(0.5) = 100
f(1.0) = 500
Three equations, three unknowns, this is solved using basic maths:
A + B = 0
A + B exp(C * 0.5) = 100
A + B exp(C) = 500
B (exp(C * 0.5) - 1) = 100
B (exp(C) - 1) = 500
exp(C) - 5 exp(C * 0.5) + 4 = 0 // this is a quadratic equation
exp(C * 0.5) = 4
C = log(16)
B = 100/3
A = -100/3
Yielding the following code:
double B = 100.0 / 3;
double C = Math.Log(16.0);
DisplayValue = B * (Math.Exp(C * SliderValue) - 1.0);
You can see that the display value is at 100 when the internal value is in the middle:
Edit: since a generic formula was requested, here it is. Given:
f(0.0) = x
f(0.5) = y
f(1.0) = z
The values for A, B and C are:
A = (xz - y²) / (x - 2y + z)
B = (y - x)² / (x - 2y + z)
C = 2 * log((z-y) / (y-x))
Note that if x - 2y + z
or y - x
is zero, there is no solution and you’ll get a division by zero. That’s because in this case, the scale is actually linear. You need to take care of that special case.
let the slider as it is and use a ValueConverter for your bindings. In the ValueConverter use the non-linear scaling to scale the value as you wish.