Malen Sie mir einen Regenbogen
-
06-07-2019 - |
Frage
Wie würden Sie gehen über die eine Reihe von RGB-Farben gleichmäßig verteilt über die spektrale Farbe Palette?So Aussehen wie ein echter Regenbogen.
Lösung
Mit HSL statt: fix die Helligkeit und Sättigung und variiert den Farbton von 0 bis 360, dann in RGB konvertieren.
HSL beschreibt Farben, wie sie von den Menschen wahrgenommen werden. RGB beschreibt sie, wie sie von Maschinen verwendet werden. So kann man nicht wirklich alles tun, optisch ansprechend direkt mit RGB.
Andere Tipps
Sie können über den HSV-Farbraum und Fuß über die Hue Dimension.
Der einfachste Ansatz besteht darin, eine lineare interpolation (in RGB) zwischen jedem aufeinanderfolgenden paar in dieser Reihenfolge:
#ff0000
rot#ffff00
gelb#00ff00
grün#00ffff
cyan#0000ff
blau#ff00ff
magenta#ff0000
zurück zu red
Dies sollte man ziemlich viel das gleiche Ergebnis wie fegen durch die Tonwerte im HSV-oder HSL, aber Sie können die Arbeit direkt in RGB.Beachten Sie, dass nur eine Komponente ändert sich für jede interpolation, die vereinfacht die Dinge.Hier ist eine Python-Implementierung:
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
- Red (Web-Farbe) (Hex: # FF0000) (RGB: 255, 0, 0)
- Orange (Farbrad orange) (Hex: # ff7f00) (RGB: 255, 127, 0)
- Gelb (Web-Farbe) (Hex: # FFFF00) (RGB: 255, 255, 0)
- Green (X11) (E-Grün) (HTML / CSS „Lime“) (Farbrad grün) (Hex: # 00FF00) (RGB: 0, 255, 0)
- Blue (Web-Farbe) (Hex: # 0000FF) (RGB: 0, 0, 255)
- Indigo (Electric Indigo) (Hex: # 6600FF) (RGB: 102, 0, 255)
- Violet (E-Violet) (Hex: # 8B00FF) (RGB: 139, 0, 255)
Zwischen jeder Farbe eine lineare Interpolation machen.
Diese Klasse wird es mit PHP tun, übergeben Sie den Konstruktor die Anzahl der Farben, die Sie in Ihrem Regenbogen wollen und die $ Sequenzeigenschaft wird ein Array von rrggbb Hex-Codes enthalten.
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;
}
}
Um zu testen, z.
$c = new color(100);
foreach($c->sequence as $col)
print "<div style='background-color:#$col'>$col</div>\n";
ich nur Kredit behauptet, dies für die Verpackung in eine Klasse, wurde die ursprüngliche Funktion in diesem Beitrag nicht gefunden: PHP HSV zu RGB Formel Verständnis
Die anderen Lösungen erfordern ziemlich große Mengen von Code und bedingte Verzweigungen, die sie ungeeignet für GPUs macht. Ich kam vor kurzem im folgenden magisch einfachen Formel in GLSL. Es ist im Wesentlichen das gleiche in 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);
}
Dies gibt Ihnen einen Regenbogen Farbe, die auf den angegebenen Farbtonwert in linearer RGB entspricht. Um in einem Bild zu verwenden, um sRGB konvertiert und dann multiplizieren mit 255.
Hier ist eine C ++ Version:
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);
}
}
Der Schlüssel ist hier zu erkennen, dass der Graph von jedem der R, G, B in Abhängigkeit von dem Farbtonwert-Koordinaten einen geklemmten Wert einer periodischen Dreiecksfunktion ist, und das kann als der absolute Wert eines Sägezahn erhalten werden, Funktion, x - floor(x)
.
Ich weiß, es ist eher alte Frage, aber hier ist meine einfache und leicht verständliche Lösung, die in den meisten Programmiersprachen einfach zu bedienen sein sollte. Ersetzen Schritte und whichStep mit Ihren eigenen Werten.
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;
}
Ich kann einen Regenbogen programmatisch mit JavaScript und HTML5 ziehen.
Ich mache einen Gradienten von rgb (255,0,0) -> rgb (255,255,0) -> rgb (0,255,0) -> rgb (0.255.255) -> rgb (0,0,255) -> rgb ( 255,0,255).
ich berechnen die Hex-Farbwerte entlang des Gradienten mit meinem RainbowVis-JS Bibliothek (die gerade Ketten Gradienten zusammen). Ich ziehe den Bogen Form mit HTML5 Canvas, Looping durch die Farben.
<!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>