Я читал несколько страниц вики и проверял разные вычисления и создавал визуализацию проекции куба RGB на шестиугольник. И я хотел бы изложить свое понимание этого обращения. Поскольку я считаю, что это преобразование (представления цветовых моделей с использованием геометрических фигур) интересно, я постараюсь быть настолько основательным, насколько я могу быть. Сначала начнем с RGB.
RGB
Ну, это на самом деле не нужно много объяснений. В простейшей форме у вас есть 3 значения, R, G и B в диапазоне [0,255]. Например, 51,153,204
. Мы можем представить его, используя гистограмму:

RGB Куб
Мы также можем представить цвет в 3D-пространстве. У нас есть три значения R
, G
, B
, что соответствует X
, Y
и Z
. Все три значения находятся в диапазоне [0,255]
, что приводит к кубу. Но прежде чем создавать кубик RGB, давайте сначала работать над 2D-пространством. Две комбинации R, G, B дают нам: RG, RB, GB. Если бы мы должны были построить график их на плоскости, мы получим следующее:

Это первые три стороны куба RGB. Если поместить их в 3D пространстве, это приводит к половине куба:

Если вы проверяете выше график, путем смешивания двух цветов, мы получаем новый цвет в точке (255,255), и это Желтый, пурпурный и голубой. Опять же, две комбинации из них дают нам: YM, YC и MC. Это недостающие стороны куба. После того, как мы добавим их, мы получаем полный куб:

и положение 51,153,204
в этом кубе:

Проекция RGB кубе на шестиугольника
сейчас что у нас есть RGB Cube, давайте проецируем его на шестиугольник. Сначала мы наклоняем куб на 45 ° на x
, а затем 35.264 ° на y
. После второго наклона черный угол находится внизу, а белый угол вверху, и оба они проходят через ось z
.

Как вы можете видеть, мы получим шестигранный взгляд, мы хотим с правильным порядком цветового тона, когда мы смотрим на куб сверху. Но нам нужно проецировать это на реальный шестиугольник. То, что мы делаем, это рисовать шестиугольник, который имеет тот же размер с видом сверху куба. Все углы шестиугольника соответствуют углам куба и цветам, а верхний угол белого куба проецируется в центр шестиугольника. Черный пропущен. И если мы сопоставим каждый цвет с шестиугольником, мы получим правильный взгляд.

И позиция 51,153,204
на шестиугольника будет:

Расчет Hue
Перед тем, как сделать расчет, давайте определим, что оттенок.
Оттенок является примерно углом вектора к точке проекции, с красным при 0 °.
... оттенок, как далеко вокруг края этого шестиугольника в точка лежит.
Это расчет из wiki-страницы HSL and HSV. Мы будем использовать его в этом объяснении.

Осмотрите шестиугольник и положение 51,153,204
на нем.

Во-первых, мы масштабировать значения R, G, B, чтобы заполнить [0,1] интервал.
R = R/255 R = 51/255 = 0.2
G = G/255 G = 153/255 = 0.6
B = B/255 B = 204/255 = 0.8
Далее найти max
и min
значения R, G, B
M = max(R, G, B) M = max(0.2, 0.6, 0.8) = 0.8
m = min(R, G, B) m = min(0.2, 0.6, 0.8) = 0.2
Затем вычислить C
(цветность). Хрома определяется как:
... chroma - это примерно расстояние от места происхождения.
Chroma относительный размер шестиугольника, проходящей через точку ...
C = OP/OP'
C = M - m
C = 0.8- 0.2 = 0.6
Теперь мы имеем R
, G
, B
и C
значения. Если мы проверим условия, if M = B
вернётся для 51,153,204
. Итак, мы будем использовать H'= (R - G)/C + 4
.
Давайте проверим шестиугольник снова. (R - G)/C
дает нам длину сегмента BP
.
segment = (R - G)/C = (0.2 - 0.6)/0.6 = -0.6666666666666666
Мы поместим этот сегмент на внутренний шестиугольник.Исходной точкой шестиугольника является R (красный) при 0 °. Если длина сегмента положительна, он должен быть на RY
, если отрицательный, он должен быть на RM
. В этом случае он отрицательный -0.6666666666666666
, и находится на краю RM
.

Далее, нам необходимо сместить положение сегмента, а точнее P₁
навтречу B
(потому что M = B
). Синий - 240°
. Шестигранник имеет 6 сторон. Каждая сторона соответствует 60°
. 240/60 = 4
. Нам нужно сдвинуть (увеличить) P₁
на 4
(что составляет 240 °). После смены P₁
будет на P
, и мы получим длину RYGCP
.
segment = (R - G)/C = (0.2 - 0.6)/0.6 = -0.6666666666666666
RYGCP = segment + 4 = 3.3333333333333335
Окружность шестиугольника 6
что соответствует 360°
. 53,151,204
Расстояние до 0°
: 3.3333333333333335
. Если мы умножим 3.3333333333333335
на 60
, мы получим его положение в градусах.
H' = 3.3333333333333335
H = H' * 60 = 200°
В случае if M = R
, так как мы размещаем один конец отрезка в R (0 °), нам не нужно сдвинуть сегмент R, если длина сегмента является положительным. Позиция P₁
будет положительной. Но если длина сегмента отрицательна, нам нужно сдвинуть его на 6, потому что отрицательное значение означает, что угловое положение больше 180 °, и нам нужно сделать полный поворот.
Таким образом, ни голландское wiki-решение hue = (g - b)/c;
, ни решение wiki для Англии hue = ((g - b)/c) % 6;
будут работать на отрицательную длину сегмента. Только ответ SO hue = (g - b)/c + (g < b ? 6 : 0);
работает как с отрицательными, так и с положительными значениями.
JSFiddle: Test all three methods for rgb(255,71,99)
JSFiddle: Find a color's position in RGB Cube and hue hexagon visually
Работа Расчет Оттенок:
console.log(rgb2hue(51,153,204));
console.log(rgb2hue(255,71,99));
console.log(rgb2hue(255,0,0));
console.log(rgb2hue(255,128,0));
console.log(rgb2hue(124,252,0));
function rgb2hue(r, g, b) {
r /= 255;
g /= 255;
b /= 255;
var max = Math.max(r, g, b);
var min = Math.min(r, g, b);
var c = max - min;
var hue;
if (c == 0) {
hue = 0;
} else {
switch(max) {
case r:
var segment = (g - b)/c;
var shift = 0/60; // R°/(360°/hex sides)
if (segment < 0) { // hue > 180, full rotation
shift = 360/60; // R°/(360°/hex sides)
}
hue = segment + shift;
break;
case g:
var segment = (b - r)/c;
var shift = 120/60; // G°/(360°/hex sides)
hue = segment + shift;
break;
case b:
var segment = (r - g)/c;
var shift = 240/60; // B°/(360°/hex sides)
hue = segment + shift;
break;
}
}
return hue * 60; // hue is in [0,6], scale it up
}
на английском выглядит правильно мне, голландец, которого я не узнаю, и я не понимаю, что он говорит на странице вики. :) – Xotic750
Вот октавная реализация hsv2rgb: http://hg.savannah.gnu.org/hgweb/octave/file/549f8625a61b/scripts/image/hsv2rgb.m – knb