0

I was able to translate this from LTSpice potentiometer code by Helmut Sennewald. But math is not my thing so I'm not sure if it is possible to reverse this so that if given point on ln segment algorithm would return corresponding value on original straight segment. For now my uber naive solution is to scan the thing to get answer. Here is the original working forward code.

//power function slider 
public float projectOntoSegment(float val, float min, float max) {

    //val is location as percentage on segment
    float range = max - min;
    float tap_point = 0.2f;//knee point as percentage
    float tap_val = range * 0.05f; //how much at knee:lets say 5% of scale
    double exp = Math.log(tap_val / range) / Math.log(tap_point);
    double ratio = Math.pow(val, exp);
    float eff_val = min + (float) (range * ratio);

    //eff_val = min + (range*val);//linear

    return eff_val;
}
Tonecops
  • 127
  • 9

1 Answers1

0

I found solution with help of some stackoverflow and luck. Why is this even needed? Because it is needed at initialization phase of the logaritmic slider. Here are both methods and example use.User gives initial value that is on the logarithmic scale. It is still just wanted value not real. To get valid value wanted value must first be back mapped to be equivalent linear value on slider and subsequently feeded into forward logarihmic mapping. That results nice and smooth allaround slider experience.

//ln power log
public float projectOntoLogCurve(float input, float min, float max, float kneePoint, float kneeMount) {

    //input is location as percentage on segment
    float range = max - min;
    double exp = Math.log(kneeMount) / Math.log(kneePoint);
    double ratio = Math.pow(input, exp);
    float output = min + (float) (range * ratio);

    return output;
}

//**********************************************
//reverse ln power log
public float projectBackFromLogCurve(float ln_input, float min, float max, float kneePoint, float kneeMount) {

    //ln_input is logaritmic location  on log curve
    float range = max - min;
    float z = (ln_input - min) / range;
    double exp = Math.log(kneeMount) / Math.log(kneePoint);
    float output = (float) Math.pow(z, 1.0 / exp);
    return output;// projection from log curve to linear curve
}

Use like:

    float min = -20.0f;
    float max = 100.0f;
    float def_val = 42.0f;
    float knee_point = 0.2f; //choose point as percentage on slider
    float knee_mount = 0.05f; //choose level value at that point
    float initVal = projectBackFromLogCurve(def_val, min, max, knee_point, knee_mount);
    this.value = initVal;
    float start = projectOntoLogCurve(this.value, min, max, knee_point, knee_mount);
    //now you have valid init value for slider
    setEffectiveValue(start);
Tonecops
  • 127
  • 9