C++: Map Range

Bjarne-stroustrup
 


Given two ranges, [a1,a2] and [b1,b2]; then a value s in range [a1,a2] is linearly mapped to a value t in range [b1,b2] when:

t = b_1 + {(s - a_1)(b_2 - b_1) \over (a_2 - a_1)}

The task is to write a function/subroutine/… that takes two ranges and a real number, and returns the mapping of the real number from the first to the second range. Use this function to map values from the range [0, 10] to the range [-1, 0].

This example defines a template function to handle the mapping, using two std::pair objects to define the source and destination ranges. It returns the provided value mapped into the target range.

It’s not written efficiently; certainly, there can be fewer explicit temporary variables. The use of the template offers a choice in types for precision and accuracy considerations, though one area for improvement might be to allow a different type for intermediate calculations.

#include <iostream>
#include <utility>

template<typename tVal>
tVal map_value(std::pair<tVal,tVal> a, std::pair<tVal, tVal> b, tVal inVal)
{
	tVal inValNorm = inVal - a.first;
	tVal aUpperNorm = a.second - a.first;
	tVal normPosition = inValNorm / aUpperNorm;

	tVal bUpperNorm = b.second - b.first;
	tVal bValNorm = normPosition * bUpperNorm;
	tVal outVal = b.first + bValNorm;

	return outVal;
}

int main()
{
	std::pair<float,float> a(0,10), b(-1,0);

	for(float value = 0.0; 10.0 >= value; ++value)
	std::cout << "map_value(" << value << ") = " << map_value(a, b, value) << std::endl;

	return 0;
}

Output:

map_value(0) = -1
map_value(1) = -0.9
map_value(2) = -0.8
map_value(3) = -0.7
map_value(4) = -0.6
map_value(5) = -0.5
map_value(6) = -0.4
map_value(7) = -0.3
map_value(8) = -0.2
map_value(9) = -0.1
map_value(10) = 0

SOURCE

Content is available under GNU Free Documentation License 1.2.