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. The function will convert 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 applied to the to-range. Use this equation to compute toValue
and return it from your function.
There’s no shape to generate in this exercise. You will this function frequently in the future shapes.