stevieb: I don't know how rusty your algebra is, but it's always good to go back to first principles: what you're doing is a liner transformation from an input number to an output number. So let's derive it using everybody's favorite line, y = mx + b. The y are your output points (y0 = $new_min and y1 = $new_max), the x are you input points (x0 = $min and x1 = $max). Then let's calculate a y from a given x (where x = $tap). (We'll ignore the fact that you called the output $x, just to confuse us, until the very end.)
#I# y0 = m*x0 + b
#II# y1 = m*x1 + b
Want to eliminate b, so we're down to one unknown:
#III# (y1-y0) = m*(x1-x0) + (b-b) #II#-#I#
#IV# (y1-y0) = m*(x1-x0) ## simplify
#V# m = (y1-y0)/(x1-x0) ## solve for m
Now we need to solve for b
#VI# y0 = (y1-y0)/(x1-x0)*x0 + b #V# into #I#
#VII# b = y0 - x0*(y1-y0)/(x1-x0) ## solve for b
Plug into the generic equation
#VIII# y = m*x + b ## generic
#IX# y = (y1-y0)/(x1-x0)*x + y0 - x0*(y1-y0)/(x1-x0) #V# and #VII# into #VIII#
#X# y = ( (y1-y0)*x - (y1-y0)*x0 )/(x1-x0) + y0 ## bring most over common denominator
#XI# y = ( y1*(x-x0) - y0*(x-x0) )/(x1-x0) + y0 ## group the y1's and the x1's
#XII# y = ( (y1-y0)*(x-x0) )/(x1-x0) + y0 ## combine the multipliers of (x-x0)
#XIII# y = (x-x0)*(y1-y0)/(x1-x0) + y0 ## reorder, remove extra parens
Convert to your notation
x0 => $min
x1 => $max
x => $tap
y0 => $new_min
y1 => $new_max
y => $x
y = (x-$min)*(y1-y0)/(x1-$min) + y0 ## substitute for x0 into #XIII#
y = (x-$min)*(y1-y0)/($max-$min) + y0 ## substitute for x1 into prev
y = ($tap-$min)*(y1-y0)/($max-$min) + y0 ## substitute for x into prev
y = ($tap-$min)*(y1-$new_min)/($max-$min) + $new_min ## substitute for y0 into prev
y = ($tap-$min)*($new_max-$new_min)/($max-$min) + $new_min ## substitute for y1 into prev
$x = ($tap-$min)*($new_max-$new_min)/($max-$min) + $new_min ## substitute for y into prev
And with my and the end semicolon, you now have the equation that typbalt89 gave: my $x = ($tap-$min)*($new_max-$new_min)/($max-$min) + $new_min;
|