Нормализуйте значения в диапазоне от -1 до 1 - PullRequest
0 голосов
/ 10 декабря 2018

Я хочу обработать значения джойстика таким образом, чтобы «нормализованные» значения лежали между -1 и 1 (включая числа с десятичными разрядами, например, 0,0129).

В частности, я имею дело свходной сигнал контроллера Wiimote.

Ось X имеет диапазон от 35 до 228, а ось Y имеет диапазон от 27 до 220.

Центр для обоих - 128.

Теперь я хотел бы сделать так, чтобы значение 35 на оси X приводило к -1, значение 128 должно давать 0, а значение 228 - 1.

Есть ли какой-то особый способ сделать это?

Лучшее, что я мог придумать, было:

public float[] GetStickNormalizedDataXY() 
{
    float[] ret = new float[2];

    ret[0] = _stick[0];
    ret[0] -= 35;
    ret[1] = stick[1];
    ret[1] -= 27;

    for (int x = 0; x < 2; x++)
    {
        ret[x] /= 193f;
    }

    return ret;
}

Но мои результаты варьируются только от 0 до 1, поэтому я думаю, что ядолжно быть, здесь что-то не так.

Ответы [ 2 ]

0 голосов
/ 10 декабря 2018

Если вы хотите создать красивую плавную функцию, которая принимает конкретные выходные значения при 3 определенных входных значениях, самое простое, что нужно сделать, - это использовать квадратичный полином.Это означает что-то вида out = Ax ^ 2 + Bx + C, где out - выход, а x - вход.Подключите (x, out) = (35, -1), (128, 0) и (228,1), чтобы получить 3 уравнения, и решите для A, B и C, чтобы получить вашу функцию отображения оси x.

Если вы хотите более интуитивно понятный способ сделать точно то же самое, что и , то вы можете интерполировать две простые линейные функции, например:

float mapX(float x)
{
   float xmin=35, xc=128, xmax=228;
   // this line is correct for xmin and xc
   float out1 -(x-xc)/(xmin-xc);
   // this line is correct for xmax and xc
   float out2 = (x-xc)/(xmax-xc);
   // interpolate to use out1 at xmin and out2 at xmax
   return out1 + (out2-out1)*(x-xmin)/(xmax-xmin);
}
0 голосов
/ 10 декабря 2018

Это должно сработать:

float[] NormalizeStickData(float[] stickData)
{
    return new[]
        { 
            Normalize(stickData[0], 35, 228, 128, -1, 1, 0),
            Normalize(stickData[1], 27, 220, 128, -1, 1, 0)
        };
}

float Normalize(float value, float oldMin, float oldMax, float oldMid, float newMin, float newMax, float newMid)
{
    if (value < oldMid)
        return Interpolate(value, oldMin, oldMid, newMin, newMid);
    else if (value > oldMid)
        return Interpolate(value, oldMid, oldMax, newMid, newMax);
    else
        return newMid;
}

float Interpolate(float value, float oldMin, float oldMax, float newMin, float newMax)
{
    return (float)(newMin + (newMax - newMin)*(value - oldMin)/(oldMax - oldMin));
}

Пример

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