Search code examples
javascriptmathrangealgebra

Javascript: using a math function to control an output range according to an input range


If I know that a ratio of two input variables "a/b" has a range of [1;2] And if I want my output value of "y" to have a range of [ymin;ymax] of my choice, based on the range of "a/b":

Is there a formula that can bind those two ranges so that I can always find the value of y, whatever the value of "a/b" (knowing it will always be between 1 and 2)?

Practically:

I have a grid that I can zoom. The number of zoom steps can't be predicted but I know that the ending scale divided by the starting scale will always be between 1 and 2. And according to that predictable range, I would like to proportionally output an opacity value to my gridlines going from a min value to a max value of my choice.

So let say, I would like my opacity values to range from 0.12 to 0.38 (it's just an example) according to the zoom level:

The formula will make sure that if the scale ratio is 1 then the opacity will be 0.12 and if the scale ratio is 2, then the opacity will be 0.38. And all opacity values In between would remain "proportional" (an increase of scale of 50% = an increase of opacity of 50%, etc..). And that should work for any output range of my choice.

So I wonder if looking for a formula to achieve this is reasonable or if it's harder to compute than it seems.

Something like this

let opacity[from desired min to max] = (endScale/startScale)[from 1 to 2] * something + opacityMin;

But that's linear and would probably not fit my needs...

I tried to plot some points on paper in order to figure that out. Here is what I ploted with the 0.12 to 0.38 example, considering the same progression within the input range and the output range:

Input      Output   percentage   multiplier
--------------------------------------------

1          0.12     0%           (* 0.12)
1.25       0.185    25%          (* 0.148)
1.5        0.25     50%          (* 0.166..)
1.75       0.315    75%          (* 0.18)
2          0.38     100%         (* 0.19)

If I predict the output I need using some input values between 1 and 2, the coefficients are not matching of course. So I don't know how to bind those two ranges.

Any hep would be appreciated. At least to get some guidance.


Solution

  • I'm not sure if there is an existing good algorithm for that, but from your description of the problem I can recommend doing something like that:

    const zoomMin = 1;
    const zoomMax = 2;
    const opacityMin = 0.12;
    const opacityMax = 0.38;
    
    function getOpacityLevel(zoomLevel) {
      const zoomRange = (zoomMax - zoomMin);
      const opacityRange = (opacityMax - opacityMin);
      
      const zoomLevelPercent = (zoomLevel - zoomMin) / zoomRange;
      const opacityLevel = (opacityRange * zoomLevelPercent) + opacityMin;
      
      return opacityLevel;
    }
    
    
    console.log(getOpacityLevel(1.0));
    console.log(getOpacityLevel(1.25));
    console.log(getOpacityLevel(1.5));
    console.log(getOpacityLevel(1.75));
    console.log(getOpacityLevel(2.0));