Функция цветового пространства HSL to RGB, которую я написал, не работает должным образом - PullRequest
0 голосов
/ 27 февраля 2019

Я написал функцию HSL to RGB, основанную на нескольких учебных пособиях, которые я нашел в Интернете, и в основном на основе библиотеки Lua под названием Colors , однако она не работает должным образом.Не могли бы вы помочь мне запустить его?

Вот код:

float Hue2RGB(float m1, float m2, float hue)
    {
        if (hue < 0) { hue += 1; };
        if (hue > 1) { hue -= 1; };

        if (hue * 6 < 1)
        {
            return m1 + (m2 - m1) * hue * 6;
        }
        else if (hue * 2 < 1)
        {
            return m2;
        }
        else if (hue * 3 < 2)
        {
            return m1 + (m2 - m1) * (2 / 3 - hue) * 6;
        }
        else
            return m1;
    }

color_RGB HSL2RGB(color_HSL color)
    {
        color.H = color.H / 360;
        float m1, m2;
        if (color.L <= 0.5)
        {
            m2 = color.L * (color.S + 1);
        }
        else
        {
            m2 = color.L + color.S - color.L * color.S;
        }

        m1 = color.L * 2 - m2;

        color_RGB return_color;
        return_color.R = Hue2RGB(m1, m2, color.H + 1 / 3);
        return_color.G = Hue2RGB(m1, m2, color.H);
        return_color.B = Hue2RGB(m1, m2, color.H - 1 / 3);
        return_color.a = 1.0;

        return return_color;
    }

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

{R=0.294117659 G=0.0980392247 B=0.125490203 ...}

Конвертировать в HSL

{H=351.600006 S=0.499999970 L=0.196078449 }

Снова конвертировать в RGB:

{R=0.0980392098 G=0.0980392098 B=0.0980392098 ...}

Я боролсяс этой проблемой уже несколько дней, и этот сайт, который я слышу, помогает людям.Спасибо.

PS: Вот моя другая функция, от RGB до HSL.Я проверял это много раз, он работает правильно:

color_HSL RGB2HSL(color_RGB color)
    {
        float min = std::fmin(std::fmin(color.R, color.G), color.B);
        float max = std::fmax(std::fmax(color.R, color.G), color.B);

        float delta = max - min;

        float H = 0, S = 0, L = ((min + max) / 2);

        if (L > 0 && L < 0.5)
        {
            S = delta / (max + min);
        }
        if (L > 0.5 && L < 1)
        {
            S = delta / (2 - max - min);
        }

        if (delta > 0)
        {

            if (max == color.R && max != color.G) { H += (color.G - color.B) / delta; }
            if (max == color.G && max != color.B) { H += 2 + (color.B - color.R) / delta; }
            if (max == color.R && max != color.R) { H += 4 + (color.R - color.G) / delta; }

            H = H / 6;
        }

        if (H < 0) { H += 1; };
        if (H > 1) { H -= 1; };

        color_HSL return_color;
        return_color.H = H * 360;
        return_color.S = S;
        return_color.L = L;

        return return_color;
    }

1 Ответ

0 голосов
/ 02 марта 2019

В C ++ (или C) результат оператора деления не является автоматически значением с плавающей запятой.Если деление и делитель имеют интегральный тип данных, то и результат деления тоже будет целым.По крайней мере, одна сторона деления должна иметь тип с плавающей запятой, чтобы получить результат с плавающей запятой.См. Арифметические операторы для получения подробной информации о правилах преобразования двоичных арифметических операций.

1, 2 и 3 являются целочисленными литералами с,поэтому тип данных этих констант является целочисленным типом данных (int).

В целом, в то время как результат 1 / 3 равен 0, а результат 2 / 3 равен 0, результат 1.0 / 3.0 равно 0.333333, а результат 2.0 / 3.0 равен 0.666667.

Обратите внимание, что это правило относится не только к делению, но и к любой другой арифметической операции.Но в случае, например, вычитания, сложения, умножения это не имеет значения, потому что эти операции генерируют (математически) интегральные результаты, когда они применяются к (математически) интегральным значениям.

Это означает, что следующие выражения не выполняют ожидаемых действий:

m1 + (m2 - m1) * (2 / 3 - hue) * 6
color.H + 1 / 3

Поскольку они совпадают с:

m1 + (m2 - m1) * (0 - hue) * 6
color.H + 0

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

float Hue2RGB(float m1, float m2, float hue)
{
    hue = hue < 0 ? hue+1 : hue > 1 ? hue-1 : hue;

    if (hue * 6 < 1)
        return m1 + (m2 - m1) * hue * 6;
    else if (hue * 2 < 1)
        return m2;
    else if (hue * 3 < 2)
        return m1 + (m2 - m1) * (2.0 / 3.0 - hue) * 6;
    else
        return m1;
}

color_RGB HSL2RGB(color_HSL color)
{
    color.H = color.H / 360;

    float m2 = color.L <= 0.5 ? color.L * (color.S + 1) : color.L + color.S - color.L * color.S;
    float m1 = color.L * 2 - m2;

    color_RGB return_color;
    return_color.R = Hue2RGB(m1, m2, color.H + 1.0 / 3.0);
    return_color.G = Hue2RGB(m1, m2, color.H);
    return_color.B = Hue2RGB(m1, m2, color.H - 1.0 / 3.0);
    return_color.a = 1.0;

    return return_color;
}
...