Подтвердить что ты не робот

Как нарисовать хорошую карту цветов RGB?

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

- (void)drawRect:(CGRect)rect
{
    CGContextRef c = UIGraphicsGetCurrentContext();

    for (float x=0; x<320; x++) {
        for (float y=0; y<416; y++) {

            float r = x / 320;
            float g = y / 416;
            float b = (y < 208) ? y / 208 : (416 - y) / 208;

            CGContextSetRGBFillColor(c, r, g, b, 1.0);
            CGContextFillRect(c, CGRectMake(x, y, 1, 1));

        }
    }
}

Результат не так уж плох, но я еще не удовлетворен. Спектр пропускает яркие цвета, включая белый. Причина ясна: красный, зеленый и синий никогда не достигнут 1.0 одновременно.

Screenshot of the resulting color map

Есть ли у вас советы по улучшению этой карты, чтобы она представляла весь спектр цветового пространства RGB?

Спасибо за ваш вклад!

UPDATE:

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

- (void)drawRect:(CGRect)rect
{
    CGContextRef c = UIGraphicsGetCurrentContext();

    int size = 20;

    for (float x=0; x<320; x+=size) {

        float s = x < 160 ? 1       : (320 - x) / 160;
        float b = x < 160 ? x / 160 : 1;

        for (float y=0; y<416; y+=size) {

            float h = y / 416;

            [[UIColor colorWithHue:h saturation:s brightness:b alpha:1.0] setFill];
            CGContextFillRect(c, CGRectMake(x, y, size, size));
        }
    }
}

В результате получается следующий результат, который идеально подходит для моих нужд.

Result using HSB color space

Спасибо за вход!

4b9b3361

Ответ 1

Ну, вы пытаетесь сгладить трехмерный объект на плоскости. Цвет RGB в основном представляет собой точку внутри куба. Отображение твердого тела RGB на поверхности может быть математически возможным, но, вероятно, не будет особенно интуитивно понятным для этой цели выбора цвета.

Возможно, вам удастся использовать HSB, который больше похож на цилиндр с оттенком как угол вокруг окружности. Вы можете "развернуть" цилиндр, отображая оттенок по координате y, а затем измените яркость или насыщенность вдоль оси x - вы можете сделать несколько простых тестов, чтобы решить, какой компонент более важен для вашего приложения. Для третьего компонента можно использовать двойной палец, если вы считаете необходимым включить его.

HSB с насыщением по оси X:
HSB map; S on X axis

С яркостью по оси X:
HSB map; B on X axis

При насыщении и яркости равны и оба по оси X:
HSB map; S=B on X axis

Если вам нужен белый цвет, который возникает, когда S = 0%, B = 100%, вы можете либо наклеить полосу вдоль одной стороны, либо попробовать S = 1/B.

Ответ 2

Я думаю, что способ его получения таков:

Горизонтально для каждого пикселя выберите соотношение r g b, такое как "0, 0, 1"

Нарисуйте пиксели сверху донизу с помощью "яркости", которая идет от 0 до 1.

Выведите каждый пиксель как pixel = brightness * (r,g,b)

Как вы идете по горизонтали, повторите R G B как:

000, 001, 010, 011, 100, 101, 110, 111

Вы можете достичь этого, используя уравнение, и обрабатывать свою интерполяцию одновременно, если вы используете 3 синусоидальных вычисления.

Это решает проблему белого и черного цвета и дает вам много цветового пространства. Если вам нужен абсолютно каждый пиксель цветового пространства, вам нужно сделать свою горизонтальную интерполяцию по-разному, и вам понадобится 2 ^ 8 вместо 8 контрольных точек.

Ответ 3

Вы пытаетесь представить трехмерное цветовое пространство на двумерной поверхности. Маловероятно, что вы найдете подходящую поверхность.

Вам понадобится выбор из двух частей.