Home > Software design >  Mapping values to sequential range
Mapping values to sequential range

Time:09-29

I get values in the Range of -360 to 360 that should be mapped to a sequence corresponding to fractions of 45. (Or any other value, Im really more interested in the mapping algorithm than the use case here).

IN -360 -315 -270 -225 -180 -135 -90 -45 0 45 90 135 180 225 270 325 360
STEP 0 1 0 -1 0 1 0 -1 0 1 0 -1 0 1 0 -1 0
OUT 0 45 0 -45 0 45 0 -45 0 45 0 -45 0 45 0 -45 0

Is there a linear Transformation I can/should use? Or how do I set up a mapping like:

var mapRange = function(base_range, target_range, s) {
  return target_range[0]   (s - base_range[0]) * (target_range[1] - target_range[0]) / (base_range[1] - base_range[0]);
};

for this?

edit: Added the desired output. Thought breaking it down to a -1 to 1 range would imply the trivial *45

CodePudding user response:

What you are looking for is a triangle wave, which can be computed using this formula:

4 * a / p * abs(((i - p / 4) % p) - p / 2) - a

Note that % in the formula is modulo, not remainder, so in JavaScript we need to define a function to return the expected result (see the docs, and some sample functions here).

In your case, a (the amplitude) is 1, and p (the period) is 180. You can write a function to compute the value and then use it to compute individual values:

const mod = (n, m) => ((n % m)   m) % m

const triWave = (i, a, p) => 4 * a / p * Math.abs(mod(i - p / 4, p) - p / 2) - a

console.log(triWave(22.5, 1, 180))
console.log(triWave(-56.25, 1, 180))

const inp = Array.from({ length: 17 }, (_, i) => -360   45 * i)
const steps = inp.map(i => triWave(i, 1, 180))

console.log(steps)

  • Related