Если вы говорите только об 11 основных цветах (например, красный, оранжевый, желтый, зеленый, голубой, синий, фиолетовый, пурпурный, черный, белый, серый), я бы сказал, что вы уже там. Сопоставление оттенков - это все, что вам нужно для сопоставления самих цветов, если они находятся в разумном диапазоне от S и L.
На мой взгляд, любой L больше 95ish достаточно близок к белому, а любой L меньше 5ish достаточно близко к черному.
Затем, если ваш S меньше, скажем, 10, ваши варианты - черный, серый и белый, в зависимости от L, и вы даже можете использовать те же правила. Черный ‹= 5, Белый> = 95, иначе серый.
Чтобы сопоставить оттенок, используя мой пример списка цветов, вы не можете использовать однородный диапазон, поскольку различия между цветами на красном конце спектра намного меньше, чем на голубом конце. Вы можете определить их вручную или получить неплохие результаты, используя логистическую функцию.
TL: DR; Математика, наверное, излишняя.
Я бы просто посмотрел на оттенок, потому что создавать формулу для этого не нужно и сложно.
С учетом сказанного, вот моя попытка логистической функции, которая соответствует восприятию общих цветов.
Вы можете настроить значение k по своему усмотрению. Я думаю, что 1.1 дает разумный разброс (хотя я пробовал только пару значений). Число 8 дает вам количество значений, которые вы хотели бы получить из этой функции. Итак, поскольку у нас есть 8 разных цветов, которые мы пытаемся сопоставить (помимо черного, белого и серого), я использовал 8.
3 сдвигает домен вправо на 3 единицы. Я использовал 3, потому что это половина области, которую мы собираемся использовать для этой функции (3 единицы по обе стороны от средней точки).
Чтобы уточнить, это последняя функция:
Для x эта формула настроена так, чтобы иметь минимум 0 и максимум 6, и он будет начинаться с голубого. Итак, если 0 <= f(x) < 1
, он зеленый; если 1 <= f(x) < 2
он голубой и т. д.
Поскольку он начинается с голубого, вам нужно настроить входное значение оттенка так, чтобы 0 был эквивалентен самому краю того, что вы считаете голубым, а не зеленым. Давайте возьмем 150 для этого примера. Это означает, что голубой цвет имеет ширину 60 градусов, откуда я взял значение 1,1 K, так как оно хорошо совпадает.
Тогда наше значение x будет x = ((hue + (360 - 150)) % 360) / 60.0
или x = (hue + 210) % 360) / 60.0
Затем мы можем подключить это к нашему f (x) и получить число от 0 до 8, которое мы можем использовать, чтобы получить наш предполагаемый цвет. Если мы сделаем массив цветов, мы можем просто минимизировать значение и использовать его в качестве индекса, так как наш домен 0-6 даст нам диапазон примерно 0,36-7,7, поэтому он никогда не превысит 8 или ниже 0.
[cyan, blue, purple, magenta, red, orange, yellow, green]
Это перебор? Наверное.
Это интереснее? Определенно.
Наконец, код
function hsl($h, $s, $l){
$options = array("cyan", "blue", "purple", "magenta", "red", "orange", "yellow", "green");
if($l >= 95)
return "white";
else if($l <= 5)
return "black";
else if($s <= 10)
return "gray";
//Convert hue to x value
$x = (($h + 210) % 360) / 60.0;
$match = matchHue($x);
return $options[$match];
}
function matchHue($x){
return intval(floor(8 / (1 + pow(M_E, (-1.1 * ($x - 3))))));
}
Все это зависит от вашего варианта использования и от того, какие цвета вы пытаетесь использовать, так что ymmv, но если вам нужна формула, а не жестко закодированный список, такая логистическая функция, вероятно, будет вашим лучшим выбором для отражения воспринимаемого цвета из оттенков.
Еще больше перебор. Почему бы и нет?
Если вам нужно больше вариантов с S и L, например, чтобы иметь дополнительные оттенки цвета, вы можете использовать тот же стиль логистической функции или даже просто линейную функцию.
Легкость подчиняется той же функции. Средне-серый будет самым большим сегментом круговой диаграммы, поэтому вы должны установить x = 0 как нижнюю границу среднего серого.
Насыщенность - это скорее логарифмическая функция. Первые 25% или около того имеют несколько узнаваемых оттенков, а верхние 75% - гораздо меньше. Что-то вроде
Где N - количество распознаваемых оттенков. Область этой функции - 0-100, а диапазон - 0-N. Вы можете настроить k по своему вкусу, чтобы изменить ширину ступенек, но даже если оставить k равным 1, вы получите адекватные результаты.
person
David
schedule
17.07.2019
50
(в RGB или другом) находится в диапазоне0 - 255
, это значение находится на0.1961
от полного диапазона. Вы также можете объединить все каналы, чтобы получить такое значение. Теперь представьте, что вы сопоставляете свои основные цвета с диапазонами от0
до1
, вы можете просто сопоставить свой0.1961
с одним из этих цветов. - person bkis   schedule 17.07.2019