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)