Я читал несколько страниц вики и проверял различные вычисления и создавал визуализации проекции куба RGB на шестиугольник. И я хотел бы опубликовать свое понимание этого преобразования. Поскольку я нахожу это преобразование (представление цветовых моделей с использованием геометрических фигур) интересным, я постараюсь быть максимально тщательным. Во-первых, начнем с RGB.
RGB
Что ж, на самом деле это не требует особых объяснений. В простейшей форме у вас есть 3 значения: R, G и B в диапазоне [0,255]. Например, 51,153,204
. Мы можем представить это с помощью гистограммы:
RGB куб
Мы также можем представить цвет в трехмерном пространстве. У нас есть три значения R
, G
, B
, которые соответствуют X
, Y
и Z
. Все три значения находятся в диапазоне [0,255]
, в результате получается куб. Но прежде чем создавать куб RGB, давайте сначала поработаем с 2D-пространством. Две комбинации R, G, B дают нам: RG, RB, GB. Если бы мы изобразили их на плоскости, мы получили бы следующее:
Это первые три стороны куба RGB. Если мы разместим их в трехмерном пространстве, получится полукуб:
Если вы проверите приведенный выше график, смешав два цвета, мы получим новый цвет (255,255), а это желтый, пурпурный и голубой. Опять же, две их комбинации дают нам: YM, YC и MC. Это недостающие стороны куба. Как только мы их добавим, мы получим законченный куб:
И положение 51,153,204
в этом кубе:
Проекция RGB-куба на шестиугольник
Теперь, когда у нас есть RGB-куб, давайте спроецируем его на шестиугольник. Сначала мы наклоняем куб на 45 ° на x
, а затем на 35,264 ° на y
. После второго наклона черный угол находится внизу, а белый угол - вверху, и оба они проходят через ось z
.
Как видите, мы получаем желаемый шестиугольник с правильным порядком оттенков, когда смотрим на куб сверху. Но нам нужно спроецировать это на настоящий шестиугольник. Что мы делаем, так это рисуем шестиугольник того же размера, что и вид сверху куба. Все углы шестиугольника соответствуют углам куба и цветов, а верхний угол белого куба проецируется на центр шестиугольника. Черный опущен. И если мы сопоставим каждый цвет с шестиугольником, мы получим правильный взгляд.
А положение 51,153,204
на шестиугольнике будет следующим:
Расчет оттенка
Прежде чем производить расчет, давайте определимся, что такое оттенок.
Оттенок - это примерно угол вектора к точке проекции, красный - 0 °.
... оттенок - это то, как далеко от края шестиугольника лежит острие.
Это расчет со страницы вики HSL и 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
(цветность). Цветность определяется как:
... цветность - это примерно расстояние точки от начала координат.
Цветность - это относительный размер шестиугольника, проходящего через точку ...
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 °, и нам нужно сделать полный поворот.
Таким образом, ни голландское вики-решение hue = (g - b) / c;
, ни русское вики-решение hue = ((g - b) / c) % 6;
не будут работать для отрицательной длины сегмента. Только ответ SO hue = (g - b) / c + (g < b ? 6 : 0);
работает как для отрицательных, так и для положительных значений.
JSFiddle: протестируйте все три метода для rgb (255,71,99)
JSFiddle: определение положения цвета в кубе RGB и визуальное изменение оттенка шестиугольника
Расчет рабочего оттенка:
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
}
person
akinuri
schedule
25.08.2016