Как вы могли бы сделать диапазон цветов RGB равномерно распределенным по спектральному цветовому диапазону? Чтобы выглядеть как настоящая радуга.
Нарисуй мне Радугу
Ответ 1
Вместо этого используйте HSL: исправьте яркость и насыщенность и измените оттенок от 0 до 360, а затем преобразуйте в RGB.
HSL описывает цвета, поскольку они воспринимаются людьми. RGB описывает их, поскольку они используются машинами. Таким образом, вы не можете делать ничего визуально приятным прямо с помощью RGB.
Ответ 2
Вы можете использовать цветовое пространство HSV и пройти через измерение оттенка.
Ответ 3
Самый простой способ - сделать линейную интерполяцию (в RGB) между каждой последовательной парой в этой последовательности:
-
#ff0000
красный -
#ffff00
желтый -
#00ff00
зеленый -
#00ffff
cyan -
#0000ff
синий -
#ff00ff
magentali > -
#ff0000
назад к красному
Это приведет к тому, что вы получите почти такой же результат, как и просмотр значений оттенков в HSV или HSL, но позволяет работать непосредственно в RGB. Обратите внимание, что для каждой интерполяции изменяется только один компонент, что упрощает работу. Здесь реализована реализация Python:
def rainbow():
r, g, b = 255, 0, 0
for g in range(256):
yield r, g, b
for r in range(255, -1, -1):
yield r, g, b
for b in range(256):
yield r, g, b
for g in range(255, -1, -1):
yield r, g, b
for r in range(256):
yield r, g, b
for b in range(255, -1, -1):
yield r, g, b
Ответ 4
- Красный (веб-цвет) (Hex: # FF0000) (RGB: 255, 0, 0)
- Оранжевый (цветное колесо оранжевое) (Hex: # FF7F00) (RGB: 255, 127, 0)
- Желтый (цвет в сети) (Hex: # FFFF00) (RGB: 255, 255, 0)
- Зеленый (X11) (электрический зеленый) (HTML/CSS "Известь" ) (Цветное колесо зеленое) (Hex: # 00FF00) (RGB: 0, 255, 0)
- Синий (веб-цвет) (Hex: # 0000FF) (RGB: 0, 0, 255)
- Indigo (Electric Indigo) (Hex: # 6600FF) (RGB: 102, 0, 255)
- Фиолетовый (Electric Violet) (Hex: # 8B00FF) (RGB: 139, 0, 255)
Между каждым цветом производится линейная интерполяция.
Ответ 5
Этот класс будет делать это с помощью PHP, передайте конструктору количество цветов, которые вы хотите в своей радуге, и свойство $sequence будет содержать массив шестнадцатеричных кодов rrggbb.
class color
{
public $sequence = array();
/**
* constructor fills $sequence with a list of colours as long as the $count param
*/
public function __construct($count, $s = .5, $l = .5)
{
for($h = 0; $h <= .85; $h += .85/$count) //.85 is pretty much in the middle of the violet spectrum
{
$this->sequence[] = color::hexHSLtoRGB($h, $s, $l);
}
}
/**
* from https://stackoverflow.com/questions/3597417/php-hsv-to-rgb-formula-comprehension#3642787
*/
public static function HSLtoRGB($h, $s, $l)
{
$r = $l;
$g = $l;
$b = $l;
$v = ($l <= 0.5) ? ($l * (1.0 + $s)) : (l + $s - l * $s);
if ($v > 0){
$m;
$sv;
$sextant;
$fract;
$vsf;
$mid1;
$mid2;
$m = $l + $l - $v;
$sv = ($v - $m ) / $v;
$h *= 6.0;
$sextant = floor($h);
$fract = $h - $sextant;
$vsf = $v * $sv * $fract;
$mid1 = $m + $vsf;
$mid2 = $v - $vsf;
switch ($sextant)
{
case 0:
$r = $v;
$g = $mid1;
$b = $m;
break;
case 1:
$r = $mid2;
$g = $v;
$b = $m;
break;
case 2:
$r = $m;
$g = $v;
$b = $mid1;
break;
case 3:
$r = $m;
$g = $mid2;
$b = $v;
break;
case 4:
$r = $mid1;
$g = $m;
$b = $v;
break;
case 5:
$r = $v;
$g = $m;
$b = $mid2;
break;
}
}
return array('r' => floor($r * 255.0),
'g' => floor($g * 255.0),
'b' => floor($b * 255.0)
);
}
//return a hex code from hsv values
public static function hexHSLtoRGB($h, $s, $l)
{
$rgb = self::HSLtoRGB($h, $s, $l);
$hex = base_convert($rgb['r'], 10, 16) . base_convert($rgb['g'], 10, 16) . base_convert($rgb['b'], 10, 16);
return $hex;
}
}
Чтобы проверить, например:
$c = new color(100);
foreach($c->sequence as $col)
print "<div style='background-color:#$col'>$col</div>\n";
Я только беру кредит за упаковку этого в класс, оригинальная функция была найдена в этом сообщении: PHP HSV для понимания формулы RGB
Ответ 6
Я знаю, что это довольно старый вопрос, но вот мое простое и понятное решение, которое должно быть простым в использовании на большинстве языков программирования. Замените шаги и какие шаги со своими собственными значениями.
int steps = 1280;
int stepChange = 1280 / steps;
int change = stepChange * whichStep;
int r=0, g=0, b=0;
if (change < 256)
{
r = 255;
g += change;
}
else if (change < 512)
{
r = 511 - change;
g = 255;
}
else if (change < 768)
{
g = 255;
b = change-512;
}
else if (change < 1024)
{
g = 1023 - change;
b = 255;
}
else
{
r = change - 1024;
b = 255;
}
Ответ 7
Другие решения требуют довольно больших количеств кода и условного разветвления, что делает их непригодными для графических процессоров. Недавно я получил следующую магически простую формулу в GLSL. Это по сути то же самое в OpenCL:
vec3 HueToRGB(float hue) {
vec3 h = vec3(hue, hue + 1.0/3.0, hue + 2.0/3.0);
return clamp(6.0 * abs(h - floor(h) - 0.5) - 1.0, 0.0, 1.0);
}
Это даст вам цвет радуги, который соответствует заданному значению оттенка в линейном RGB. Чтобы использовать в изображении, конвертируйте в sRGB, а затем умножьте на 255.
Вот версия С++:
float clamp(float value, float low, float high) {
return value < low ? low : (value > high ? high : value);
}
void HueToRGB(float hue, float *rgb) {
rgb[0] = hue;
rgb[1] = hue + 1.f/3.f;
rgb[2] = hue + 2.f/3.f;
for (unsigned i = 0; i < 3; ++i) {
rgb[i] = clamp(6.0f * fabsf(rgb[i] - floorf(rgb[i]) - 0.5f) - 1.f, 0.f, 1.f);
}
}
Ключ здесь состоит в том, чтобы понять, что график каждой из координат R, G, B в функции значения оттенка является зажатым значением функции периодического треугольника и может быть получен как абсолютное значение пилообразного функция, x - floor(x)
.
Ответ 8
Я могу рисовать радугу программно с помощью JavaScript и HTML5.
Я делаю градиент от rgb (255,0,0) → rgb (255,255,0) → rgb (0,255,0) → rgb (0,255,255) → rgb (0,0,255) → rgb ( 255,0,255).
Я вычисляю шестнадцатеричные значения цвета вдоль градиента, используя мою библиотеку RainbowVis-JS (которая просто объединяет градиенты). Я рисую форму дуги с помощью холста HTML5, перемещаясь по цветам.
<!DOCTYPE html>
<html>
<head>
<script src="rainbowvis.js"></script>
</head>
<body>
<script type="text/javascript">
window.onload = function(){
var RAINBOW_WIDTH = 60;
var RAINBOW_RADIUS = 130;
// Library class
var rainbow = new Rainbow();
rainbow.setNumberRange(1, RAINBOW_WIDTH);
rainbow.setSpectrum(
'FF0000', 'FFFF00', '00FF00',
'00FFFF', '0000FF', 'FF00FF'
);
// Canvas
var canvas = document.getElementById('MyCanvas');
var context = canvas.getContext('2d');
context.lineWidth = 1;
for (var i = 1; i <= RAINBOW_WIDTH; i++) {
context.beginPath();
context.arc(canvas.width/2, canvas.width/2, RAINBOW_RADIUS - i+1,
Math.PI, 0, false);
context.strokeStyle = '#' + rainbow.colourAt(i); // Library function
context.stroke();
}
};
</script>
<canvas id="MyCanvas" width="300" height="300">
<p>Rainbow arc example. Your browser doesn't support canvas.</p>
</canvas>
</body>
</html>