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;


In reply to Re^6: Normalizing a range of numbers to a percentage by pryrt
in thread Normalizing a range of numbers to a percentage by stevieb

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.