teaching machines

Range-mapping

June 4, 2021 by . Filed under public, slai-2021.

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:

$$C = \frac{5}{9}(F – 32)$$

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:

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:

$$\frac{\mathrm{fromHi} – \mathrm{fromLo}}{\mathrm{toHi} – \mathrm{toLo}} = \frac{\mathrm{fromValue} – \mathrm{fromLo}}{\mathrm{toValue} – \mathrm{toLo}}$$

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:

$$\begin{align}\frac{\mathrm{fromHi} – \mathrm{fromLo}}{\mathrm{toHi} – \mathrm{toLo}} &= \frac{\mathrm{fromValue} – \mathrm{fromLo}}{\mathrm{toValue} – \mathrm{toLo}} \\\frac{\mathrm{toValue} – \mathrm{toLo}}{\mathrm{toHi} – \mathrm{toLo}} &= \frac{\mathrm{fromValue} – \mathrm{fromLo}}{\mathrm{fromHi} – \mathrm{fromLo}} \\\mathrm{toValue} – \mathrm{toLo} &= \frac{\mathrm{fromValue} – \mathrm{fromLo}}{\mathrm{fromHi} – \mathrm{fromLo}} \cdot (\mathrm{toHi} – \mathrm{toLo}) \\\mathrm{toValue} &= \frac{\mathrm{fromValue} – \mathrm{fromLo}}{\mathrm{fromHi} – \mathrm{fromLo}} \cdot (\mathrm{toHi} – \mathrm{toLo}) + \mathrm{toLo} \\\end{align}$$

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.