Exponential map() function?

edited October 2016 in How To...

Is it possible to create a mapping of values that outputs a logarithmic (exponential) value instead of linear? I need to program something similar as a knob or slider, controlling a filter cutoff frequency... (that's exactly what I need it for :)

Cheers, H.

Tagged:

Answers

  • Is it possible? Sure. But you're probably going to have to do it yourself, since I don't think there's a logMap() function or anything.

    But this isn't as complicated as it might sound. Take a look at the Processing source to see how the map() function works. Most of it is done in a single line:

    float outgoing =
      start2 + (stop2 - start2) * ((value - start1) / (stop1 - start1));
    

    You're going to have to come up with a similar formula that does your logarithmic mapping. Try writing down a few input numbers with the output that you want for them until you see a pattern.

  • Ok, thanks! I will have to do some reading on how exactly are thos sliders / knobs working :)

  • Answer ✓

    A similar question has been asked before. This discussion might help.

  • Ok, I did this (I think it works fine):

        float mapLog(float value, float start1, float stop1, float start2, float stop2) {
          start2 = log(start2);
          stop2 = log(stop2);
    
          float outgoing =
            exp(start2 + (stop2 - start2) * ((value - start1) / (stop1 - start1)));
    
          String badness = null;
          if (outgoing != outgoing) {
            badness = "NaN (not a number)";
    
          } else if (outgoing == Float.NEGATIVE_INFINITY ||
                     outgoing == Float.POSITIVE_INFINITY) {
            badness = "infinity";
          }
          if (badness != null) {
            final String msg =
              String.format("map(%s, %s, %s, %s, %s) called, which returns %s",
                            nf(value), nf(start1), nf(stop1),
                            nf(start2), nf(stop2), badness);
            PGraphics.showWarning(msg);
          }
          return outgoing;
        }
    

    I got the idea from this post: http://stackoverflow.com/questions/846221/logarithmic-slider

  • edited May 2018

    More examples of non-linear interpolation / mapping methods (common in music and animation software) include sinusoidal, cubic, etc.

    For simple examples (in C++) check out "Interpolation methods" (Paul Bourke, 1999).

    Notice that rather than writing a map for each, you could also write different versions of lerp() -- linear: lerp(), cubic: "cerp()", sinusoidal in/out: "sierp()" / "soerp()", etc. etc. -- and then feed the interpolated value into the basic map(), e.g.:

    float w1=0;
    float w2=480;
    float c1=0;
    float c2=255;
    
    println( map(  lerp(w1,w2,0.5), w1, w2, c1, c2) );
    println( map( sierp(w1,w2,0.5), w1, w2, c1, c2) );
    println( map(  cerp(w1,w2,0.5), w1, w2, c1, c2) );
    

    Edit: For examples of using built-in bezier functions to do curve-based interpolation, see:

Sign In or Register to comment.