Математическая функция для увеличения воспринимаемой линейности ползунка громкости - PullRequest
0 голосов
/ 18 июня 2019

Фон

Я не математик, но я точно знаю, что мне нужно.Пожалуйста, согласитесь с моим нематематическим объяснением.

Синопсис

Я хотел бы помочь с функцией javascript, которая отобразит ползунок ввода на выходное число, сследующие два требования.Я управляю цифровым микшером, но с простым отношением x - 100 = y он действительно нечувствителен в нижней части слайдера и действительно чувствителен в верхней части.Позже я буду управлять другими устройствами, такими как диммеры освещения, поэтому я хотел бы понять как можно больше о таких функциях, без необходимости углубляться в математику.

  • Входные значениявсегда от 0 до 100, и выходные значения в диапазоне от -99 до указанного числа от x до y, например, 0 или 5. (т. е. это число должно быть легко изменено в функции.)

  • Должен быть нелинейным, как кривая, показанная ниже (выходной сигнал изменяется быстрее в нижней части ползунка), однако это должна быть более крутая кривая.Я не могу работать с математикой, как это сделать.Я попробовал обе математические функции ln () и log () на графическом калькуляторе, но не смог найти то, что мне нужно.На самом деле, я хотел бы понять, что мне нужно сделать, чтобы задать или настроить кривую следующими двумя способами: крутизной кривой и способом зеркального отражения кривой, чтобы в начале изменения были БОЛЬШИМИ, а нечто я описал выше.

enter image description here

1 Ответ

1 голос
/ 18 июня 2019

Возможности бесконечны, так что это будет предположение. Используя ту же формулу, с которой вы пытались работать, то есть с квадратным корнем x , можно определить три параметра:

  • Значение Y, при котором кривая должна пересекать ось Y
  • Значение X, при котором кривая должна пересекать ось X
  • Величина кривизны (изгиб)

На последний параметр может влиять изменение мощности, которую вы применяете к x . Так что, если вы будете использовать 1/3 вместо 1/2, то изгиб будет сильнее.

Довольно просто увидеть, как первые два параметра влияют на функцию.

Вот функция, которая возвращает фактическую функцию на основе этих трех параметров:

function createFunc(y0, x0, power) {
    const inv = 10 / power;
    const c = y0 / (x0 ** inv);
    return function f(x) {
        return c * (x ** inv) - y0;
    }
}

Число 10 в этой логике позволяет power быть целым числом и быть достаточно чувствительным. Таким образом, для квадратного корня вы должны передать значение 20: тогда inv становится 1 / 2.

Вот небольшая демонстрация, позволяющая в интерактивном режиме изменить эти три параметра и увидеть полученный график:

const inputs = document.querySelectorAll("input");
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
const shiftX = 10.5;
const shiftY = 10.5;
ctx.translate(shiftX, shiftY);
const rangeX = [-shiftX, canvas.width-shiftX];
const rangeY = [-shiftY, canvas.height-shiftY];

function display(f) {
    ctx.clearRect(rangeX[0], rangeY[0], rangeX[1], rangeY[1]);
    
    ctx.beginPath();
    ctx.strokeStyle = "black";
    ctx.lineWidth = 1;

    ctx.moveTo(rangeX[0], 0);
    ctx.lineTo(rangeX[1], 0);

    ctx.moveTo(0, rangeY[0]);
    ctx.lineTo(0, rangeY[1]);
    
    for (let i = 10; i < canvas.width; i+= 10) {
        ctx.moveTo(i, -2); ctx.lineTo(i, +2);
    }
    for (let i = 10; i < canvas.height; i+= 10) {
        ctx.moveTo(-2, i); ctx.lineTo(+2, i);
    }
    ctx.stroke();
    if (!f) return;
    
    ctx.beginPath();
    ctx.strokeStyle = "red";
    ctx.moveTo(0, f(0));
    for (let x = 0; x < rangeX[1]; x++) {
        ctx.lineTo(x, f(x));
    }
    ctx.stroke();
}
function createFunc(y0, x0, power) {
    const inv = 10 / power;
    const c = y0 / (x0 ** inv);
    return function f(x) {
        return c * (x ** inv) - y0;
    }
}

function update() {
    const f = createFunc(+inputs[0].value, +inputs[1].value, +inputs[2].value);
    display(f);
}

document.oninput = update;
update();
canvas { background: #eee; float: left }
<canvas></canvas><br>
Play with these numbers!<br>
Cross Y-axis at: <input type="number" min="-130" max="-10" value="-100"><br>
Cross X-axis at: <input type="number" min="10" max="200" value="100"><br>
Bend: <input type="number" min="10" max="200" value="20"><br>

Полученный график прилипает довольно близко к оси Y. Аналогичное исследование и построение графиков можно выполнить с помощью логарифма, где с помощью третьего параметра вы измените base логарифма.

Существует много других методов, таких как кривые Безье. См., Например, Криволинейный фитинг .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...