## Range-mapping

*This post is part of a course on geometric modeling at the Summer Liberal Arts Institute for Computer Science held at Carleton College in 2021.*

When you go to the doctor’s office, you may see a chart on the wall suggesting different ways of measuring the severity of your pain. Consider this chart, for example, which lets place your pain on a scale of colors, facial expressions, qualitative terms, or numbers from 0 to 10. Whatever scale you choose, the doctor likely converts your rating to a numeric quantity when recording it. The process of converting a value found on one range to an equal value found on a corresponding range is called *range-mapping*.

If you’ve been somewhere other than the United States, you’ve likely done a lot of range-mapping between temperature scales. In your coursework, you have likely encountered this function that range-maps a Fahrenheit quantity to a Celsius quantity:

Writing a temperature conversion program seems to be a rite of passage for novice programmers. In this exercise, you will one-up all those novice programmers by writing a general-purpose range-mapping function. It will work for converting any number on one scale to its corresponding number on another scale.

### Function

Write a function named `rangeMap`

. Have it accept these parameters:

- The
`toLo`

value, which is the lowest value on the scale to which you are converting. In Fahrenheit-to-Celsius conversion, this value would be 0. - The
`toHi`

value, which is the highest value on the scale to which you are converting. In Fahrenheit-to-Celsius conversion, this value would be 100. - The
`fromLo`

value, which is the lowest value on the scale from which you are converting. In Fahrenheit-to-Celsius conversion, this value would be 32. - The
`fromHi`

value, which is the highest value on the scale from which you are converting. In Fahrenheit-to-Celsius conversion, this value would be 212. - The
`fromValue`

, which is the value on the scale from which you are converting.

Have the function return 0 for the time being.

### Similar Triangles

Now you must work out the arithmetic for mapping one range to another. You know that `fromLo`

must map to `toLo`

. You also know that `fromHi`

must map to `toHi`

. If you were to plot your conversion function on a graph, you’d know that it would pass through these xy-pairings:

What should happen when you try to map a value halfway between `fromLo`

and `fromHi`

? Your function should produce a value halfway between `toLo`

and `toHi`

. You’ll get this proportional behavior if your function is linear:

Linear functions have the form $f(x) = \mathrm{slope} * x + \mathrm{intercept}$. There are several ways that you can work out the values of the slope and intercept given the two endpoints. Personally, I find an argument made via similar triangles to be the most memorable, and that is the one I will share with you.

You know the xy-coordinates of two points of the function: $(\mathrm{fromLo}, \mathrm{toLo})$ and $(\mathrm{fromHi}, \mathrm{toHi})$. You have a third point representing the value to be converted: $(\mathrm{fromValue}, \mathrm{toValue})$, which may appear anywhere on this line:

Imagine that the line forms the hypotenuse of two right triangles, a big one that spans both ranges and a smaller one that runs up to the mapping you are trying to figure out:

When two triangles are similar, their side lengths are in the same proportion. You work out the side lengths by examining the differences between the x- and y-coordinates.

When you relate the widths and heights of the two triangles, you get this equation:

You know five of these variables because they are given to you as parameters. You don’t know $\mathrm{toValue}$; that’s the value you are trying to compute. You can solve for it through these steps:

If you are looking for some intuition behind this equation, the fraction on the right-hand side converts the value into a proportion within the from-range. This proportion is then scaled and offset into the to-range. Use this equation to compute `toValue`

and return it from your function.

## Leave a Reply